group_settings: Show all, active and deactivated groups.

Fixes #32877.
Co-authored-by: Sanchit Sharma <ssharmas10662@gmail.com>

Thanks to @sanchi-t, I've yanked a lot of code and approach
from his concurrent PR in 32475, especially the method of
toggling parent css class to hide/show relevant children.
This commit is contained in:
apoorvapendse
2025-01-05 07:52:37 +05:30
committed by Tim Abbott
parent 47e622f5a5
commit d12feb1872
7 changed files with 156 additions and 10 deletions

View File

@@ -24,6 +24,7 @@ import type {Toggle} from "./components.ts";
import * as compose_banner from "./compose_banner.ts";
import * as confirm_dialog from "./confirm_dialog.ts";
import * as dialog_widget from "./dialog_widget.ts";
import * as dropdown_widget from "./dropdown_widget.ts";
import * as group_permission_settings from "./group_permission_settings.ts";
import type {
GroupGroupSettingName,
@@ -57,6 +58,7 @@ import * as user_groups from "./user_groups.ts";
import type {UserGroup} from "./user_groups.ts";
import * as user_profile from "./user_profile.ts";
import * as util from "./util.ts";
import * as views_util from "./views_util.ts";
type ActiveData = {
$row: JQuery | undefined;
@@ -64,8 +66,15 @@ type ActiveData = {
$tabs: JQuery;
};
let filters_dropdown_widget: dropdown_widget.DropdownWidget;
export const FILTERS = {
ACTIVE_AND_DEACTIVATED_GROUPS: $t({defaultMessage: "Active and deactivated"}),
ACTIVE_GROUPS: $t({defaultMessage: "Active groups"}),
DEACTIVATED_GROUPS: $t({defaultMessage: "Deactivated groups"}),
};
export let toggler: Toggle;
export let select_tab = "general";
const initial_group_filter = FILTERS.ACTIVE_GROUPS;
let group_list_widget: ListWidget.ListWidget<UserGroup, UserGroup>;
let group_list_toggler: Toggle;
@@ -1321,6 +1330,7 @@ export function update_group(event: UserGroupUpdateEvent, group: UserGroup): voi
}
if (event.data.deactivated) {
$("#user-group-edit-filter-options").show();
handle_deleted_group(group.id);
return;
}
@@ -1393,6 +1403,14 @@ export function change_state(
if (/\d+/.test(section)) {
const group_id = Number.parseInt(section, 10);
const group = user_groups.get_user_group_from_id(group_id);
const group_visibility = group.deactivated
? FILTERS.DEACTIVATED_GROUPS
: FILTERS.ACTIVE_GROUPS;
update_displayed_groups(group_visibility);
if (filters_dropdown_widget) {
filters_dropdown_widget.render(group_visibility);
}
show_right_section();
select_tab = right_side_tab;
@@ -1425,9 +1443,9 @@ function compare_by_name(a: UserGroup, b: UserGroup): number {
function redraw_left_panel(tab_name: string): void {
let groups_list_data;
if (tab_name === "all-groups") {
groups_list_data = user_groups.get_realm_user_groups();
groups_list_data = user_groups.get_realm_user_groups(true);
} else if (tab_name === "your-groups") {
groups_list_data = user_groups.get_user_groups_of_user(people.my_current_user_id());
groups_list_data = user_groups.get_user_groups_of_user(people.my_current_user_id(), true);
}
if (groups_list_data === undefined) {
return;
@@ -1450,6 +1468,7 @@ export function switch_group_tab(tab_name: string): void {
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);
}
@@ -1550,6 +1569,69 @@ export function remove_deactivated_user_from_all_groups(user_id: number): void {
}
}
export function update_displayed_groups(filter_id: string): void {
if (filter_id === FILTERS.ACTIVE_GROUPS) {
$(".user-groups-list").addClass("hide-deactived-user-groups");
$(".user-groups-list").removeClass("hide-active-user-groups");
} else if (filter_id === FILTERS.DEACTIVATED_GROUPS) {
$(".user-groups-list").removeClass("hide-deactived-user-groups");
$(".user-groups-list").addClass("hide-active-user-groups");
} else {
$(".user-groups-list").removeClass("hide-deactived-user-groups");
$(".user-groups-list").removeClass("hide-active-user-groups");
}
}
export function filter_click_handler(
event: JQuery.TriggeredEvent,
dropdown: tippy.Instance,
widget: dropdown_widget.DropdownWidget,
): void {
event.preventDefault();
event.stopPropagation();
const filter_id = z.string().parse(widget.value());
update_displayed_groups(filter_id);
update_empty_left_panel_message();
dropdown.hide();
widget.render();
}
function filters_dropdown_options(current_value: string | number | undefined): {
unique_id: string;
name: string;
bold_current_selection: boolean;
}[] {
return [
{
unique_id: FILTERS.ACTIVE_GROUPS,
name: FILTERS.ACTIVE_GROUPS,
bold_current_selection: current_value === FILTERS.ACTIVE_GROUPS,
},
{
unique_id: FILTERS.DEACTIVATED_GROUPS,
name: FILTERS.DEACTIVATED_GROUPS,
bold_current_selection: current_value === FILTERS.DEACTIVATED_GROUPS,
},
{
unique_id: FILTERS.ACTIVE_AND_DEACTIVATED_GROUPS,
name: FILTERS.ACTIVE_AND_DEACTIVATED_GROUPS,
bold_current_selection: current_value === FILTERS.ACTIVE_AND_DEACTIVATED_GROUPS,
},
];
}
function setup_dropdown_filters_widget(): void {
filters_dropdown_widget = new dropdown_widget.DropdownWidget({
...views_util.COMMON_DROPDOWN_WIDGET_PARAMS,
get_options: filters_dropdown_options,
widget_name: "user_group_visibility_settings",
item_click_callback: filter_click_handler,
$events_container: $("#user-group-edit-filter-options"),
default_id: initial_group_filter,
});
filters_dropdown_widget.setup();
}
export function setup_page(callback: () => void): void {
function initialize_components(): void {
group_list_toggler = components.toggle({
@@ -1563,7 +1645,13 @@ export function setup_page(callback: () => void): void {
},
});
if (user_groups.realm_has_deactivated_user_groups()) {
$("#user-group-edit-filter-options").show();
} else {
$("#user-group-edit-filter-options").hide();
}
group_list_toggler.get().prependTo("#groups_overlay_container .list-toggler-container");
setup_dropdown_filters_widget();
}
function populate_and_fill(): void {
@@ -1583,7 +1671,7 @@ export function setup_page(callback: () => void): void {
$("#groups_overlay_container"),
);
$groups_overlay_container.html(groups_overlay_html);
update_displayed_groups(initial_group_filter);
const context = {
banner_type: compose_banner.INFO,
classname: "group_info",

View File

@@ -140,6 +140,13 @@ export function get_user_group_from_name(name: string): UserGroup | undefined {
return user_group_name_dict.get(name);
}
export function realm_has_deactivated_user_groups(): boolean {
const realm_user_groups = get_realm_user_groups(true);
const deactivated_group_count = realm_user_groups.filter((group) => group.deactivated).length;
return deactivated_group_count > 0;
}
export function get_realm_user_groups(include_deactivated = false): UserGroup[] {
const user_groups = [...user_group_by_id_dict.values()].sort((a, b) => a.id - b.id);
return user_groups.filter((group) => {
@@ -299,8 +306,11 @@ export function is_setting_group_empty(setting_group: GroupSettingValue): boolea
return true;
}
export function get_user_groups_of_user(user_id: number): UserGroup[] {
const user_groups_realm = get_realm_user_groups();
export function get_user_groups_of_user(
user_id: number,
include_deactivated_groups = false,
): UserGroup[] {
const user_groups_realm = get_realm_user_groups(include_deactivated_groups);
const groups_of_user = user_groups_realm.filter((group) => is_user_in_group(group.id, user_id));
return groups_of_user;
}

View File

@@ -647,10 +647,20 @@ h4.user_group_setting_subsection_title {
.group_name_search_section {
padding: 8px 10px;
display: grid;
grid-template: "search-input clear-search" auto / minmax(0, 1fr) 30px;
grid-template:
"search-input clear-search more-options-button" auto / minmax(0, 1fr)
30px;
border-bottom: 1px solid var(--color-border-modal-bar);
}
#user_group_visibility_settings_widget {
grid-area: more-options-button;
margin-left: 10px;
display: flex;
gap: 3px;
width: auto;
}
.user-groups-list,
.streams-list {
position: relative;
@@ -664,6 +674,31 @@ h4.user_group_setting_subsection_title {
width: 100%;
}
.left .group-name .fa-ban,
.right .group-name .fa-ban {
font-size: 0.8em;
opacity: 0.6;
}
.left .group-name,
.right .group-name {
display: flex;
gap: 3px;
align-items: center;
}
.user-groups-list.hide-deactived-user-groups .deactivated-group {
display: none;
}
.user-groups-list.hide-active-user-groups .group-row:not(.deactivated-group) {
display: none;
}
.user_group_visibility_settings-dropdown-list-container .dropdown-list-wrapper {
min-width: 11em;
}
#search_group_name:placeholder-shown + #clear_search_group_name {
visibility: hidden;
}

View File

@@ -71,7 +71,7 @@
<span class="popover-group-menu-placeholder"><i>{{t 'This group has no members.'}}</i></span>
{{/if}}
</li>
{{#unless (or is_guest is_system_group deactivated)}}
{{#unless (or is_guest is_system_group)}}
<li role="separator" class="popover-menu-separator hidden-for-spectators"></li>
<li role="none" class="link-item popover-menu-list-item hidden-for-spectators">
<a href="{{group_edit_url}}" role="menuitem" class="navigate-link-on-enter popover-menu-link" tabindex="0">

View File

@@ -1,4 +1,4 @@
<div class="group-row" data-group-id="{{id}}" data-group-name="{{name}}">
<div class="group-row {{#if deactivated}}deactivated-group{{/if}}" data-group-id="{{id}}" data-group-name="{{name}}">
{{#if is_member}}
<div class="check checked join_leave_button tippy-zulip-tooltip {{#unless can_leave}}disabled{{/unless}} {{#unless is_direct_member}}not-direct-member{{/unless}}" data-tooltip-template-id="{{#if can_leave}}{{#if is_direct_member}}leave-{{name}}-group-tooltip-template{{else}}cannot-leave-{{name}}-because-of-subgroup-tooltip-template{{/if}}{{else}}cannot-leave-{{name}}-group-tooltip-template{{/if}}">
<template id="leave-{{name}}-group-tooltip-template">
@@ -56,7 +56,11 @@
{{/if}}
<div class="group-info-box">
<div class="top-bar">
<div class="group-name">{{name}}</div>
<div class="group-name">{{name}}
{{#if deactivated}}
<i class="fa fa-ban deactivated-user-icon"></i>
{{/if}}
</div>
</div>
<div class="bottom-bar">
<div class="description rendered_markdown" data-no-description="{{t 'No description.'}}">{{description}}</div>

View File

@@ -19,7 +19,11 @@
<div class="group_general_settings group_setting_section" data-group-section="general">
<div class="group-header">
<div class="group-name-wrapper">
<span class="group-name" title="{{group_name}}">{{group_name}}</span>
<span class="group-name" title="{{group.name}}">{{group.name}}
{{#if group.deactivated}}
<i class="fa fa-ban deactivated-user-icon"></i>
{{/if}}
</span>
</div>
<div class="group_change_property_info alert-notification"></div>
<div class="button-group">

View File

@@ -25,6 +25,11 @@
<button type="button" class="clear_search_button" id="clear_search_group_name">
<i class="zulip-icon zulip-icon-close" aria-hidden="true"></i>
</button>
<span>
<label class="checkbox" id="user-group-edit-filter-options">
{{> ../dropdown_widget widget_name="user_group_visibility_settings"}}
</label>
</span>
</div>
<div class="no-groups-to-show">
<div class="your_groups_tab_empty_text">