diff --git a/tools/test-js-with-node b/tools/test-js-with-node index b6d4a50e6d..bea99fb268 100755 --- a/tools/test-js-with-node +++ b/tools/test-js-with-node @@ -257,7 +257,6 @@ EXEMPT_FILES = make_set( "web/src/user_group_popover.js", "web/src/user_group_ui_updates.js", "web/src/user_groups.ts", - "web/src/user_groups_settings_ui.js", "web/src/user_profile.js", "web/src/user_settings.ts", "web/src/user_sort.js", diff --git a/web/src/hashchange.js b/web/src/hashchange.js index 75d690665a..6c79143e5b 100644 --- a/web/src/hashchange.js +++ b/web/src/hashchange.js @@ -29,7 +29,7 @@ import * as sidebar_ui from "./sidebar_ui"; import * as spectators from "./spectators"; import * as stream_settings_ui from "./stream_settings_ui"; import * as ui_report from "./ui_report"; -import * as user_groups_settings_ui from "./user_groups_settings_ui"; +import * as user_group_edit from "./user_group_edit"; import {user_settings} from "./user_settings"; // Read https://zulip.readthedocs.io/en/latest/subsystems/hashchange-system.html @@ -263,7 +263,7 @@ function do_hashchange_overlay(old_hash) { } if (base === "groups") { - user_groups_settings_ui.change_state(section); + user_group_edit.change_state(section); } if (base === "settings") { @@ -328,7 +328,7 @@ function do_hashchange_overlay(old_hash) { } if (base === "groups") { - user_groups_settings_ui.launch(section); + user_group_edit.launch(section); return; } diff --git a/web/src/server_events_dispatch.js b/web/src/server_events_dispatch.js index 4419a8d128..a766d31cd0 100644 --- a/web/src/server_events_dispatch.js +++ b/web/src/server_events_dispatch.js @@ -81,7 +81,6 @@ import * as unread_ui from "./unread_ui"; import * as user_events from "./user_events"; import * as user_group_edit from "./user_group_edit"; 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"; import * as user_topics_ui from "./user_topics_ui"; @@ -862,7 +861,7 @@ export function dispatch_normal_event(event) { case "add": user_groups.add(event.group); if (overlays.groups_open()) { - user_groups_settings_ui.add_group_to_table(event.group); + user_group_edit.add_group_to_table(event.group); } break; case "remove": @@ -885,7 +884,7 @@ export function dispatch_normal_event(event) { break; case "update": user_groups.update(event); - user_groups_settings_ui.update_group(event.group_id); + user_group_edit.update_group(event.group_id); break; default: blueslip.error("Unexpected event type user_group/" + event.op); diff --git a/web/src/ui_init.js b/web/src/ui_init.js index 3ab3316b5e..fefe1a3a5f 100644 --- a/web/src/ui_init.js +++ b/web/src/ui_init.js @@ -137,7 +137,6 @@ import * as user_group_edit from "./user_group_edit"; import * as user_group_edit_members from "./user_group_edit_members"; import * as user_group_popover from "./user_group_popover"; import * as user_groups from "./user_groups"; -import * as user_groups_settings_ui from "./user_groups_settings_ui"; import * as user_profile from "./user_profile"; import {initialize_user_settings, user_settings} from "./user_settings"; import * as user_status from "./user_status"; @@ -619,7 +618,6 @@ export function initialize_everything() { user_topics.initialize(user_topics_params); muted_users.initialize(muted_users_params); stream_settings_ui.initialize(); - user_groups_settings_ui.initialize(); left_sidebar_navigation_area.initialize(); stream_list.initialize({ on_stream_click(stream_id, trigger) { diff --git a/web/src/user_group_edit.js b/web/src/user_group_edit.js index 902161e840..f4d2c43f9e 100644 --- a/web/src/user_group_edit.js +++ b/web/src/user_group_edit.js @@ -1,8 +1,10 @@ import $ from "jquery"; import render_confirm_delete_user from "../templates/confirm_dialog/confirm_delete_user.hbs"; +import render_browse_user_groups_list_item from "../templates/user_group_settings/browse_user_groups_list_item.hbs"; import render_change_user_group_info_modal from "../templates/user_group_settings/change_user_group_info_modal.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"; import * as browser_history from "./browser_history"; @@ -12,6 +14,7 @@ import * as confirm_dialog from "./confirm_dialog"; import * as dialog_widget from "./dialog_widget"; import * as hash_util from "./hash_util"; import {$t, $t_html} from "./i18n"; +import * as ListWidget from "./list_widget"; import * as overlays from "./overlays"; import {page_params} from "./page_params"; import * as people from "./people"; @@ -19,13 +22,18 @@ import * as scroll_util from "./scroll_util"; import * as settings_data from "./settings_data"; import * as stream_ui_updates from "./stream_ui_updates"; import * as ui_report from "./ui_report"; +import * as user_group_create from "./user_group_create"; import * as user_group_edit_members from "./user_group_edit_members"; import * as user_groups from "./user_groups"; -import * as user_groups_settings_ui from "./user_groups_settings_ui"; +import * as util from "./util"; export let toggler; export let select_tab = "group_general_settings"; +let group_list_widget; +let group_list_toggler; +let active_group_id; + function setup_group_edit_hash(group) { const hash = hash_util.group_edit_url(group); browser_history.update(hash); @@ -142,17 +150,15 @@ export function handle_member_edit_event(group_id, user_ids) { // and current user is among the affect users as in that // case the group widget list need to be updated and show // or remove the group-row on the left panel accordingly. - const tab_key = user_groups_settings_ui.get_active_data().$tabs.first().attr("data-tab-key"); + const tab_key = get_active_data().$tabs.first().attr("data-tab-key"); if (tab_key === "your-groups" && user_ids.includes(people.my_current_user_id())) { - user_groups_settings_ui.redraw_user_group_list(); + redraw_user_group_list(); } // update display of check-mark. - if (user_groups_settings_ui.is_group_already_present(group)) { + if (is_group_already_present(group)) { const is_member = user_groups.is_user_in_group(group_id, people.my_current_user_id()); - const $sub_unsub_button = user_groups_settings_ui - .row_for_group_id(group_id) - .find(".sub_unsub_button"); + const $sub_unsub_button = row_for_group_id(group_id).find(".sub_unsub_button"); if (is_member) { $sub_unsub_button.removeClass("disabled"); $sub_unsub_button.addClass("checked"); @@ -219,7 +225,7 @@ export function setup_group_list_tab_hash(tab_key_value) { We do not update the hash based on tab switches if a group is currently being edited. */ - if (user_groups_settings_ui.get_active_data().id !== undefined) { + if (get_active_data().id !== undefined) { return; } @@ -232,9 +238,32 @@ export function setup_group_list_tab_hash(tab_key_value) { } } +export const show_user_group_settings_pane = { + nothing_selected() { + $("#groups_overlay .settings, #user-group-creation").hide(); + reset_active_group_id(); + $("#groups_overlay .nothing-selected").show(); + $("#groups_overlay .user-group-info-title").text( + $t({defaultMessage: "User group settings"}), + ); + }, + settings(group) { + $("#groups_overlay .nothing-selected, #user-group-creation").hide(); + $("#groups_overlay .settings").show(); + set_active_group_id(group.id); + $("#groups_overlay .user-group-info-title").text(group.name); + }, + create_user_group() { + $("#groups_overlay .nothing-selected, #groups_overlay .settings").hide(); + reset_active_group_id(); + $("#user-group-creation").show(); + $("#groups_overlay .user-group-info-title").text($t({defaultMessage: "Create user group"})); + }, +}; + function open_right_panel_empty() { $(".group-row.active").removeClass("active"); - user_groups_settings_ui.show_user_group_settings_pane.nothing_selected(); + show_user_group_settings_pane.nothing_selected(); const tab_key = $(".user-groups-container") .find("div.ind-tab.selected") .first() @@ -246,7 +275,7 @@ export function is_editing_group(desired_group_id) { if (!overlays.groups_open()) { return false; } - return user_groups_settings_ui.get_active_data().id === desired_group_id; + return get_active_data().id === desired_group_id; } export function handle_deleted_group(group_id) { @@ -257,13 +286,13 @@ export function handle_deleted_group(group_id) { if (is_editing_group(group_id)) { open_right_panel_empty(); } - user_groups_settings_ui.redraw_user_group_list(); + redraw_user_group_list(); } export function show_group_settings(group) { $(".group-row.active").removeClass("active"); - user_groups_settings_ui.show_user_group_settings_pane.settings(group); - user_groups_settings_ui.row_for_group_id(group.id).addClass("active"); + show_user_group_settings_pane.settings(group); + row_for_group_id(group.id).addClass("active"); setup_group_edit_hash(group); setup_group_settings(group); } @@ -273,6 +302,304 @@ export function open_group_edit_panel_for_row(group_row) { show_group_settings(group); } +export function set_active_group_id(group_id) { + active_group_id = group_id; +} + +export function reset_active_group_id() { + active_group_id = undefined; +} + +// Ideally this should be included in page params. +// Like we have page_params.max_stream_name_length` and +// `page_params.max_stream_description_length` for streams. +export const max_user_group_name_length = 100; + +export function set_up_click_handlers() { + $("#groups_overlay").on("click", ".left #clear_search_group_name", (e) => { + const $input = $("#groups_overlay .left #search_group_name"); + $input.val(""); + + // This is a hack to rerender complete + // stream list once the text is cleared. + $input.trigger("input"); + + e.stopPropagation(); + e.preventDefault(); + }); +} + +function create_user_group_clicked() { + // this changes the tab switcher (settings/preview) which isn't necessary + // to a add new stream title. + show_user_group_settings_pane.create_user_group(); + $(".group-row.active").removeClass("active"); + + user_group_create.show_new_user_group_modal(); + $("#create_user_group_name").trigger("focus"); +} + +export function do_open_create_user_group() { + // Only call this directly for hash changes. + // Prefer open_create_user_group(). + show_right_section(); + create_user_group_clicked(); +} + +export function open_create_user_group() { + do_open_create_user_group(); + browser_history.update("#groups/new"); +} + +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_tabs = $(".user-groups-container").find("div.ind-tab.selected"); + return { + $row: row_for_group_id(active_group_id), + id: active_group_id, + $tabs: $active_tabs, + }; +} + +export function switch_to_group_row(group) { + if (is_group_already_present(group)) { + /* + It is possible that this function may be called at times + when group-row for concerned group may not be present this + might occur when user manually edits the url for a group + that user is not member of and #groups overlay is open with + your-groups tab active. + + To handle such cases we perform these steps only if the group + is listed in the left panel else we simply open the settings + for the concerned group. + */ + const $group_row = row_for_group_id(group.id); + const $container = $(".user-groups-list"); + + get_active_data().$row.removeClass("active"); + $group_row.addClass("active"); + + scroll_util.scroll_element_into_container($group_row, $container); + } + + show_group_settings(group); +} + +function show_right_section() { + $(".right").addClass("show"); + $(".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; + } + + redraw_user_group_list(); + + 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. + show_group_settings(group); + user_group_create.reset_name(); + } +} + +export function update_group(group_id) { + if (!overlays.groups_open()) { + return; + } + const group = user_groups.get_user_group_from_id(group_id); + const $group_row = row_for_group_id(group_id); + // update left side pane + $group_row.find(".group-name").text(group.name); + $group_row.find(".description").text(group.description); + + if (get_active_data().id === group.id) { + // update right side pane + update_settings_pane(group); + // update settings title + $("#groups_overlay .user-group-info-title").text(group.name); + } +} + +export function change_state(section) { + if (section === "new") { + do_open_create_user_group(); + redraw_user_group_list(); + return; + } + + if (section === "all") { + group_list_toggler.goto("all-groups"); + return; + } + + if (section === "your") { + group_list_toggler.goto("your-groups"); + return; + } + + // if the section is a valid number. + if (/\d+/.test(section)) { + const group_id = Number.parseInt(section, 10); + const group = user_groups.get_user_group_from_id(group_id); + if (!group) { + // Some users can type random url of the form + // /#groups/ we need to handle that. + group_list_toggler.goto("your-groups"); + } else { + show_right_section(); + // We show the list of user groups in the left panel + // based on the tab that is active. It is `your-groups` + // tab by default. + redraw_user_group_list(); + switch_to_group_row(group); + } + return; + } + + blueslip.info("invalid section for groups: " + section); + group_list_toggler.goto("your-groups"); +} + +function compare_by_name(a, b) { + return util.strcmp(a.name, b.name); +} + +function redraw_left_panel(tab_name) { + let groups_list_data; + if (tab_name === "all-groups") { + groups_list_data = user_groups.get_realm_user_groups(); + } else if (tab_name === "your-groups") { + groups_list_data = user_groups.get_user_groups_of_user(people.my_current_user_id()); + } + groups_list_data.sort(compare_by_name); + group_list_widget.replace_list_data(groups_list_data); +} + +export function redraw_user_group_list() { + const tab_name = get_active_data().$tabs.first().attr("data-tab-key"); + redraw_left_panel(tab_name); +} + +export function switch_group_tab(tab_name) { + /* + This switches the groups list tab, but it doesn't update + the group_list_toggler widget. You may instead want to + use `group_list_toggler.goto`. + */ + redraw_left_panel(tab_name); + setup_group_list_tab_hash(tab_name); +} + +export function setup_page(callback) { + function initialize_components() { + group_list_toggler = components.toggle({ + child_wants_focus: true, + values: [ + {label: $t({defaultMessage: "Your groups"}), key: "your-groups"}, + {label: $t({defaultMessage: "All groups"}), key: "all-groups"}, + ], + callback(_label, key) { + switch_group_tab(key); + }, + }); + + $("#groups_overlay_container .list-toggler-container").prepend(group_list_toggler.get()); + } + + function populate_and_fill() { + const template_data = { + can_create_or_edit_user_groups: settings_data.user_can_edit_user_groups(), + max_user_group_name_length, + }; + + const rendered = render_user_group_settings_overlay(template_data); + + const $groups_overlay_container = scroll_util.get_content_element( + $("#groups_overlay_container"), + ); + $groups_overlay_container.empty(); + $groups_overlay_container.append(rendered); + + // Initially as the overlay is build with empty right panel, + // active_group_id is undefined. + reset_active_group_id(); + + const $container = $("#groups_overlay_container .user-groups-list"); + + /* + As change_state function called after this initial build up + redraws left panel based on active tab we avoid building extra dom + here as the required group-rows are anyway going to be created + immediately after this due to call to change_state. So we call + `ListWidget.create` with empty user groups list. + */ + group_list_widget = ListWidget.create($container, [], { + name: "user-groups-overlay", + get_item: ListWidget.default_get_item, + modifier_html(item) { + item.is_member = user_groups.is_direct_member_of( + people.my_current_user_id(), + item.id, + ); + return render_browse_user_groups_list_item(item); + }, + filter: { + $element: $("#groups_overlay_container .left #search_group_name"), + predicate(item, value) { + return ( + item && + (item.name.toLocaleLowerCase().includes(value) || + item.description.toLocaleLowerCase().includes(value)) + ); + }, + onupdate() { + if (active_group_id !== undefined) { + const active_group = user_groups.get_user_group_from_id(active_group_id); + if (is_group_already_present(active_group)) { + row_for_group_id(active_group_id).addClass("active"); + } + } + }, + }, + init_sort: ["alphabetic", "name"], + $simplebar_container: $container, + }); + + initialize_components(); + + set_up_click_handlers(); + user_group_create.set_up_handlers(); + + // show the "User group settings" header by default. + $(".display-type #user_group_settings_title").show(); + + if (callback) { + callback(); + } + } + + populate_and_fill(); +} + export function initialize() { $("#groups_overlay_container").on("click", ".group-row", function (e) { if ($(e.target).closest(".check, .user_group_settings_wrapper").length === 0) { @@ -288,7 +615,7 @@ export function initialize() { const template_data = { group_name: user_group.name, group_description: user_group.description, - max_user_group_name_length: user_groups_settings_ui.max_user_group_name_length, + max_user_group_name_length, }; const change_user_group_info_modal = render_change_user_group_info_modal(template_data); dialog_widget.launch({ @@ -310,7 +637,7 @@ export function initialize() { }); $("#groups_overlay_container").on("click", ".group_settings_header .btn-danger", () => { - const active_group_data = user_groups_settings_ui.get_active_data(); + const active_group_data = get_active_data(); const group_id = active_group_data.id; const user_group = user_groups.get_user_group_from_id(group_id); @@ -366,4 +693,36 @@ export function initialize() { dialog_widget.submit_api_request(channel.patch, url, data); } + + $("#groups_overlay_container").on("click", ".create_user_group_button", (e) => { + e.preventDefault(); + open_create_user_group(); + }); + + $("#groups_overlay_container").on("click", ".group-row", show_right_section); + + $("#groups_overlay_container").on("click", ".fa-chevron-left", () => { + $(".right").removeClass("show"); + $(".user-groups-header").removeClass("slide-left"); + }); +} + +export function launch(section) { + setup_page(() => { + overlays.open_overlay({ + name: "group_subscriptions", + $overlay: $("#groups_overlay"), + on_close() { + browser_history.exit_overlay(); + }, + }); + change_state(section); + }); + if (!get_active_data().id) { + if (section === "new") { + $("#create_user_group_name").trigger("focus"); + } else { + $("#search_group_name").trigger("focus"); + } + } } diff --git a/web/src/user_groups_settings_ui.js b/web/src/user_groups_settings_ui.js deleted file mode 100644 index ecf03b612e..0000000000 --- a/web/src/user_groups_settings_ui.js +++ /dev/null @@ -1,377 +0,0 @@ -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_overlay from "../templates/user_group_settings/user_group_settings_overlay.hbs"; - -import * as blueslip from "./blueslip"; -import * as browser_history from "./browser_history"; -import * as components from "./components"; -import {$t} from "./i18n"; -import * as ListWidget from "./list_widget"; -import * as overlays from "./overlays"; -import * as people from "./people"; -import * as scroll_util from "./scroll_util"; -import * as settings_data from "./settings_data"; -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 util from "./util"; - -let group_list_widget; -let group_list_toggler; -let active_group_id; - -export function set_active_group_id(group_id) { - active_group_id = group_id; -} - -export function reset_active_group_id() { - active_group_id = undefined; -} - -// Ideally this should be included in page params. -// Like we have page_params.max_stream_name_length` and -// `page_params.max_stream_description_length` for streams. -export const max_user_group_name_length = 100; - -export function set_up_click_handlers() { - $("#groups_overlay").on("click", ".left #clear_search_group_name", (e) => { - const $input = $("#groups_overlay .left #search_group_name"); - $input.val(""); - - // This is a hack to rerender complete - // stream list once the text is cleared. - $input.trigger("input"); - - e.stopPropagation(); - e.preventDefault(); - }); -} - -export const show_user_group_settings_pane = { - nothing_selected() { - $("#groups_overlay .settings, #user-group-creation").hide(); - reset_active_group_id(); - $("#groups_overlay .nothing-selected").show(); - $("#groups_overlay .user-group-info-title").text( - $t({defaultMessage: "User group settings"}), - ); - }, - settings(group) { - $("#groups_overlay .nothing-selected, #user-group-creation").hide(); - $("#groups_overlay .settings").show(); - set_active_group_id(group.id); - $("#groups_overlay .user-group-info-title").text(group.name); - }, - create_user_group() { - $("#groups_overlay .nothing-selected, #groups_overlay .settings").hide(); - reset_active_group_id(); - $("#user-group-creation").show(); - $("#groups_overlay .user-group-info-title").text($t({defaultMessage: "Create user group"})); - }, -}; - -function create_user_group_clicked() { - // this changes the tab switcher (settings/preview) which isn't necessary - // to a add new stream title. - show_user_group_settings_pane.create_user_group(); - $(".group-row.active").removeClass("active"); - - user_group_create.show_new_user_group_modal(); - $("#create_user_group_name").trigger("focus"); -} - -export function do_open_create_user_group() { - // Only call this directly for hash changes. - // Prefer open_create_user_group(). - show_right_section(); - create_user_group_clicked(); -} - -export function open_create_user_group() { - do_open_create_user_group(); - browser_history.update("#groups/new"); -} - -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_tabs = $(".user-groups-container").find("div.ind-tab.selected"); - return { - $row: row_for_group_id(active_group_id), - id: active_group_id, - $tabs: $active_tabs, - }; -} - -export function switch_to_group_row(group) { - if (is_group_already_present(group)) { - /* - It is possible that this function may be called at times - when group-row for concerned group may not be present this - might occur when user manually edits the url for a group - that user is not member of and #groups overlay is open with - your-groups tab active. - - To handle such cases we perform these steps only if the group - is listed in the left panel else we simply open the settings - for the concerned group. - */ - const $group_row = row_for_group_id(group.id); - const $container = $(".user-groups-list"); - - get_active_data().$row.removeClass("active"); - $group_row.addClass("active"); - - scroll_util.scroll_element_into_container($group_row, $container); - } - - user_group_edit.show_group_settings(group); -} - -function show_right_section() { - $(".right").addClass("show"); - $(".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; - } - - redraw_user_group_list(); - - 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. - user_group_edit.show_group_settings(group); - user_group_create.reset_name(); - } -} - -export function update_group(group_id) { - if (!overlays.groups_open()) { - return; - } - const group = user_groups.get_user_group_from_id(group_id); - const $group_row = row_for_group_id(group_id); - // update left side pane - $group_row.find(".group-name").text(group.name); - $group_row.find(".description").text(group.description); - - if (get_active_data().id === group.id) { - // update right side pane - user_group_edit.update_settings_pane(group); - // update settings title - $("#groups_overlay .user-group-info-title").text(group.name); - } -} - -export function change_state(section) { - if (section === "new") { - do_open_create_user_group(); - redraw_user_group_list(); - return; - } - - if (section === "all") { - group_list_toggler.goto("all-groups"); - return; - } - - if (section === "your") { - group_list_toggler.goto("your-groups"); - return; - } - - // if the section is a valid number. - if (/\d+/.test(section)) { - const group_id = Number.parseInt(section, 10); - const group = user_groups.get_user_group_from_id(group_id); - if (!group) { - // Some users can type random url of the form - // /#groups/ we need to handle that. - group_list_toggler.goto("your-groups"); - } else { - show_right_section(); - // We show the list of user groups in the left panel - // based on the tab that is active. It is `your-groups` - // tab by default. - redraw_user_group_list(); - switch_to_group_row(group); - } - return; - } - - blueslip.info("invalid section for groups: " + section); - group_list_toggler.goto("your-groups"); -} - -function compare_by_name(a, b) { - return util.strcmp(a.name, b.name); -} - -function redraw_left_panel(tab_name) { - let groups_list_data; - if (tab_name === "all-groups") { - groups_list_data = user_groups.get_realm_user_groups(); - } else if (tab_name === "your-groups") { - groups_list_data = user_groups.get_user_groups_of_user(people.my_current_user_id()); - } - groups_list_data.sort(compare_by_name); - group_list_widget.replace_list_data(groups_list_data); -} - -export function redraw_user_group_list() { - const tab_name = get_active_data().$tabs.first().attr("data-tab-key"); - redraw_left_panel(tab_name); -} - -export function switch_group_tab(tab_name) { - /* - This switches the groups list tab, but it doesn't update - the group_list_toggler widget. You may instead want to - use `group_list_toggler.goto`. - */ - redraw_left_panel(tab_name); - user_group_edit.setup_group_list_tab_hash(tab_name); -} - -export function setup_page(callback) { - function initialize_components() { - group_list_toggler = components.toggle({ - child_wants_focus: true, - values: [ - {label: $t({defaultMessage: "Your groups"}), key: "your-groups"}, - {label: $t({defaultMessage: "All groups"}), key: "all-groups"}, - ], - callback(_label, key) { - switch_group_tab(key); - }, - }); - - $("#groups_overlay_container .list-toggler-container").prepend(group_list_toggler.get()); - } - - function populate_and_fill() { - const template_data = { - can_create_or_edit_user_groups: settings_data.user_can_edit_user_groups(), - max_user_group_name_length, - }; - - const rendered = render_user_group_settings_overlay(template_data); - - const $groups_overlay_container = scroll_util.get_content_element( - $("#groups_overlay_container"), - ); - $groups_overlay_container.empty(); - $groups_overlay_container.append(rendered); - - // Initially as the overlay is build with empty right panel, - // active_group_id is undefined. - reset_active_group_id(); - - const $container = $("#groups_overlay_container .user-groups-list"); - - /* - As change_state function called after this initial build up - redraws left panel based on active tab we avoid building extra dom - here as the required group-rows are anyway going to be created - immediately after this due to call to change_state. So we call - `ListWidget.create` with empty user groups list. - */ - group_list_widget = ListWidget.create($container, [], { - name: "user-groups-overlay", - get_item: ListWidget.default_get_item, - modifier_html(item) { - item.is_member = user_groups.is_direct_member_of( - people.my_current_user_id(), - item.id, - ); - return render_browse_user_groups_list_item(item); - }, - filter: { - $element: $("#groups_overlay_container .left #search_group_name"), - predicate(item, value) { - return ( - item && - (item.name.toLocaleLowerCase().includes(value) || - item.description.toLocaleLowerCase().includes(value)) - ); - }, - onupdate() { - if (active_group_id !== undefined) { - const active_group = user_groups.get_user_group_from_id(active_group_id); - if (is_group_already_present(active_group)) { - row_for_group_id(active_group_id).addClass("active"); - } - } - }, - }, - init_sort: ["alphabetic", "name"], - $simplebar_container: $container, - }); - - initialize_components(); - - set_up_click_handlers(); - user_group_create.set_up_handlers(); - - // show the "User group settings" header by default. - $(".display-type #user_group_settings_title").show(); - - if (callback) { - callback(); - } - } - - populate_and_fill(); -} - -export function initialize() { - $("#groups_overlay_container").on("click", ".create_user_group_button", (e) => { - e.preventDefault(); - open_create_user_group(); - }); - - $("#groups_overlay_container").on("click", ".group-row", show_right_section); - - $("#groups_overlay_container").on("click", ".fa-chevron-left", () => { - $(".right").removeClass("show"); - $(".user-groups-header").removeClass("slide-left"); - }); -} - -export function launch(section) { - setup_page(() => { - overlays.open_overlay({ - name: "group_subscriptions", - $overlay: $("#groups_overlay"), - on_close() { - browser_history.exit_overlay(); - }, - }); - change_state(section); - }); - if (!get_active_data().id) { - if (section === "new") { - $("#create_user_group_name").trigger("focus"); - } else { - $("#search_group_name").trigger("focus"); - } - } -} diff --git a/web/tests/dispatch.test.js b/web/tests/dispatch.test.js index 9b25c2c193..7f796b52b8 100644 --- a/web/tests/dispatch.test.js +++ b/web/tests/dispatch.test.js @@ -85,7 +85,6 @@ const user_events = mock_esm("../src/user_events"); const user_groups = mock_esm("../src/user_groups"); const user_group_edit = mock_esm("../src/user_group_edit"); const overlays = mock_esm("../src/overlays"); -const user_groups_settings_ui = mock_esm("../src/user_groups_settings_ui"); mock_esm("../src/giphy"); const electron_bridge = set_global("electron_bridge", {}); @@ -177,7 +176,7 @@ run_test("user groups", ({override}) => { 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); + override(user_group_edit, "add_group_to_table", user_group_settings_ui_stub.f); dispatch(event); @@ -269,7 +268,7 @@ run_test("user groups", ({override}) => { const user_group_settings_ui_stub = make_stub(); override(user_groups, "update", stub.f); - override(user_groups_settings_ui, "update_group", user_group_settings_ui_stub.f); + override(user_group_edit, "update_group", user_group_settings_ui_stub.f); dispatch(event); assert.equal(stub.num_calls, 1);