mirror of https://github.com/zulip/zulip.git
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:
parent
fdd9f018ad
commit
6147f2bd7a
|
@ -78,6 +78,8 @@ const ui = mock_esm("../../static/js/ui");
|
||||||
const unread_ops = mock_esm("../../static/js/unread_ops");
|
const unread_ops = mock_esm("../../static/js/unread_ops");
|
||||||
const user_events = mock_esm("../../static/js/user_events");
|
const user_events = mock_esm("../../static/js/user_events");
|
||||||
const user_groups = mock_esm("../../static/js/user_groups");
|
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");
|
mock_esm("../../static/js/giphy");
|
||||||
|
|
||||||
const electron_bridge = set_global("electron_bridge", {});
|
const electron_bridge = set_global("electron_bridge", {});
|
||||||
|
@ -162,10 +164,20 @@ run_test("user groups", ({override}) => {
|
||||||
override(settings_user_groups_legacy, "reload", noop);
|
override(settings_user_groups_legacy, "reload", noop);
|
||||||
{
|
{
|
||||||
const stub = make_stub();
|
const stub = make_stub();
|
||||||
|
const user_group_settings_ui_stub = make_stub();
|
||||||
|
|
||||||
override(user_groups, "add", stub.f);
|
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);
|
dispatch(event);
|
||||||
|
|
||||||
assert.equal(stub.num_calls, 1);
|
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);
|
assert_same(args.group, event.group);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -39,6 +39,10 @@ export function streams_open() {
|
||||||
return open_overlay_name === "subscriptions";
|
return open_overlay_name === "subscriptions";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function groups_open() {
|
||||||
|
return (open_overlay_name = "groups");
|
||||||
|
}
|
||||||
|
|
||||||
export function lightbox_open() {
|
export function lightbox_open() {
|
||||||
return open_overlay_name === "lightbox";
|
return open_overlay_name === "lightbox";
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,6 +68,7 @@ import * as typing_events from "./typing_events";
|
||||||
import * as unread_ops from "./unread_ops";
|
import * as unread_ops from "./unread_ops";
|
||||||
import * as user_events from "./user_events";
|
import * as user_events from "./user_events";
|
||||||
import * as user_groups from "./user_groups";
|
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 {user_settings} from "./user_settings";
|
||||||
import * as user_status from "./user_status";
|
import * as user_status from "./user_status";
|
||||||
|
|
||||||
|
@ -754,6 +755,9 @@ export function dispatch_normal_event(event) {
|
||||||
switch (event.op) {
|
switch (event.op) {
|
||||||
case "add":
|
case "add":
|
||||||
user_groups.add(event.group);
|
user_groups.add(event.group);
|
||||||
|
if (overlays.groups_open()) {
|
||||||
|
user_groups_settings_ui.add_group_to_table(event.group);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case "remove":
|
case "remove":
|
||||||
user_groups.remove(user_groups.get_user_group_from_id(event.group_id));
|
user_groups.remove(user_groups.get_user_group_from_id(event.group_id));
|
||||||
|
|
|
@ -272,8 +272,8 @@ function create_stream() {
|
||||||
error(xhr) {
|
error(xhr) {
|
||||||
const msg = JSON.parse(xhr.responseText).msg;
|
const msg = JSON.parse(xhr.responseText).msg;
|
||||||
if (msg.includes("access")) {
|
if (msg.includes("access")) {
|
||||||
// If we can't access the stream, we can safely assume it's
|
// If we can't access the stream, we can safely
|
||||||
// a duplicate stream that we are not invited to.
|
// assume it's a duplicate stream that we are not invited to.
|
||||||
//
|
//
|
||||||
// BUG: This check should be using error codes, not
|
// BUG: This check should be using error codes, not
|
||||||
// parsing the error string, so it works correctly
|
// parsing the error string, so it works correctly
|
||||||
|
|
|
@ -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_groups from "./user_groups";
|
||||||
import * as user_group_settings_ui from "./user_groups_settings_ui";
|
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 {
|
class UserGroupMembershipError {
|
||||||
report_no_members_to_user_group() {
|
report_no_members_to_user_group() {
|
||||||
$("#user_group_membership_error").text(
|
$("#user_group_membership_error").text(
|
||||||
|
@ -101,6 +115,7 @@ function create_user_group() {
|
||||||
const data = {};
|
const data = {};
|
||||||
const group_name = $("#create_user_group_name").val().trim();
|
const group_name = $("#create_user_group_name").val().trim();
|
||||||
const description = $("#create_user_group_description").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
|
// 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
|
// newline characters (by pressing the Enter key) it would still be possible to copy
|
||||||
|
@ -142,6 +157,7 @@ function create_user_group() {
|
||||||
xhr,
|
xhr,
|
||||||
$(".user_group_create_info"),
|
$(".user_group_create_info"),
|
||||||
);
|
);
|
||||||
|
reset_name();
|
||||||
loading.destroy_indicator($("#user_group_creating_indicator"));
|
loading.destroy_indicator($("#user_group_creating_indicator"));
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import $ from "jquery";
|
import $ from "jquery";
|
||||||
|
|
||||||
import render_browse_user_groups_list_item from "../templates/user_group_settings/browse_user_groups_list_item.hbs";
|
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 render_user_group_settings_overlay from "../templates/user_group_settings/user_group_settings_overlay.hbs";
|
||||||
|
|
||||||
import * as blueslip from "./blueslip";
|
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 settings_data from "./settings_data";
|
||||||
import * as ui from "./ui";
|
import * as ui from "./ui";
|
||||||
import * as user_group_create from "./user_group_create";
|
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";
|
import * as user_groups from "./user_groups";
|
||||||
|
|
||||||
|
let group_list_widget;
|
||||||
|
|
||||||
export function set_up_click_handlers() {
|
export function set_up_click_handlers() {
|
||||||
$("#groups_overlay").on("click", ".left #clear_search_group_name", (e) => {
|
$("#groups_overlay").on("click", ".left #clear_search_group_name", (e) => {
|
||||||
const $input = $("#groups_overlay .left #search_group_name");
|
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)}']`);
|
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() {
|
export function get_active_data() {
|
||||||
const $active_row = $("div.group-row.active");
|
const $active_row = $("div.group-row.active");
|
||||||
const valid_active_id = Number.parseInt($active_row.attr("data-group-id"), 10);
|
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");
|
$(".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) {
|
export function change_state(section) {
|
||||||
if (!section) {
|
if (!section) {
|
||||||
show_user_group_settings_pane.nothing_selected();
|
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 $container = $("#manage_groups_container .user-groups-list");
|
||||||
const user_groups_list = user_groups.get_realm_user_groups();
|
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",
|
name: "user-groups-overlay",
|
||||||
modifier(item) {
|
modifier(item) {
|
||||||
item.is_member = user_groups.is_direct_member_of(
|
item.is_member = user_groups.is_direct_member_of(
|
||||||
|
|
Loading…
Reference in New Issue