mirror of
https://github.com/zulip/zulip.git
synced 2025-11-22 07:21:23 +00:00
user_group_create: Support adding subgroups while creating groups.
This commit is contained in:
@@ -1,6 +1,10 @@
|
|||||||
|
import * as add_subscribers_pill from "./add_subscribers_pill";
|
||||||
|
import * as input_pill from "./input_pill";
|
||||||
import * as keydown_util from "./keydown_util";
|
import * as keydown_util from "./keydown_util";
|
||||||
|
import type {User} from "./people";
|
||||||
import * as stream_pill from "./stream_pill";
|
import * as stream_pill from "./stream_pill";
|
||||||
import type {CombinedPillContainer} from "./typeahead_helper";
|
import type {CombinedPill, CombinedPillContainer} from "./typeahead_helper";
|
||||||
|
import * as user_group_create_members_data from "./user_group_create_members_data";
|
||||||
import * as user_group_pill from "./user_group_pill";
|
import * as user_group_pill from "./user_group_pill";
|
||||||
import * as user_pill from "./user_pill";
|
import * as user_pill from "./user_pill";
|
||||||
|
|
||||||
@@ -15,6 +19,39 @@ function get_pill_group_ids(pill_widget: CombinedPillContainer): number[] {
|
|||||||
return group_user_ids;
|
return group_user_ids;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function create_without_add_button({
|
||||||
|
$pill_container,
|
||||||
|
onPillCreateAction,
|
||||||
|
onPillRemoveAction,
|
||||||
|
}: {
|
||||||
|
$pill_container: JQuery;
|
||||||
|
onPillCreateAction: (pill_user_ids: number[], pill_subgroup_ids: number[]) => void;
|
||||||
|
onPillRemoveAction: (pill_user_ids: number[], pill_subgroup_ids: number[]) => void;
|
||||||
|
}): CombinedPillContainer {
|
||||||
|
const pill_widget = input_pill.create<CombinedPill>({
|
||||||
|
$container: $pill_container,
|
||||||
|
create_item_from_text: add_subscribers_pill.create_item_from_text,
|
||||||
|
get_text_from_item: add_subscribers_pill.get_text_from_item,
|
||||||
|
get_display_value_from_item: add_subscribers_pill.get_display_value_from_item,
|
||||||
|
generate_pill_html: add_subscribers_pill.generate_pill_html,
|
||||||
|
});
|
||||||
|
function get_users(): User[] {
|
||||||
|
const potential_members = user_group_create_members_data.get_potential_members();
|
||||||
|
return user_pill.filter_taken_users(potential_members, pill_widget);
|
||||||
|
}
|
||||||
|
|
||||||
|
pill_widget.onPillCreate(() => {
|
||||||
|
onPillCreateAction(get_pill_user_ids(pill_widget), get_pill_group_ids(pill_widget));
|
||||||
|
});
|
||||||
|
pill_widget.onPillRemove(() => {
|
||||||
|
onPillRemoveAction(get_pill_user_ids(pill_widget), get_pill_group_ids(pill_widget));
|
||||||
|
});
|
||||||
|
|
||||||
|
add_subscribers_pill.set_up_pill_typeahead({pill_widget, $pill_container, get_users});
|
||||||
|
|
||||||
|
return pill_widget;
|
||||||
|
}
|
||||||
|
|
||||||
export function set_up_handlers({
|
export function set_up_handlers({
|
||||||
get_pill_widget,
|
get_pill_widget,
|
||||||
$parent_container,
|
$parent_container,
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import * as user_group_pill from "./user_group_pill";
|
|||||||
import * as user_groups from "./user_groups";
|
import * as user_groups from "./user_groups";
|
||||||
import * as user_pill from "./user_pill";
|
import * as user_pill from "./user_pill";
|
||||||
|
|
||||||
function create_item_from_text(
|
export function create_item_from_text(
|
||||||
text: string,
|
text: string,
|
||||||
current_items: CombinedPill[],
|
current_items: CombinedPill[],
|
||||||
): CombinedPill | undefined {
|
): CombinedPill | undefined {
|
||||||
@@ -31,7 +31,7 @@ function create_item_from_text(
|
|||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
function get_text_from_item(item: CombinedPill): string {
|
export function get_text_from_item(item: CombinedPill): string {
|
||||||
let text: string;
|
let text: string;
|
||||||
switch (item.type) {
|
switch (item.type) {
|
||||||
case "stream":
|
case "stream":
|
||||||
@@ -47,7 +47,7 @@ function get_text_from_item(item: CombinedPill): string {
|
|||||||
return text;
|
return text;
|
||||||
}
|
}
|
||||||
|
|
||||||
function set_up_pill_typeahead({
|
export function set_up_pill_typeahead({
|
||||||
pill_widget,
|
pill_widget,
|
||||||
$pill_container,
|
$pill_container,
|
||||||
get_users,
|
get_users,
|
||||||
@@ -65,7 +65,7 @@ function set_up_pill_typeahead({
|
|||||||
pill_typeahead.set_up_combined($pill_container.find(".input"), pill_widget, opts);
|
pill_typeahead.set_up_combined($pill_container.find(".input"), pill_widget, opts);
|
||||||
}
|
}
|
||||||
|
|
||||||
function get_display_value_from_item(item: CombinedPill): string {
|
export function get_display_value_from_item(item: CombinedPill): string {
|
||||||
if (item.type === "user_group") {
|
if (item.type === "user_group") {
|
||||||
return user_group_pill.display_pill(user_groups.get_user_group_from_id(item.group_id));
|
return user_group_pill.display_pill(user_groups.get_user_group_from_id(item.group_id));
|
||||||
} else if (item.type === "stream") {
|
} else if (item.type === "stream") {
|
||||||
@@ -75,7 +75,7 @@ function get_display_value_from_item(item: CombinedPill): string {
|
|||||||
return user_pill.get_display_value_from_item(item);
|
return user_pill.get_display_value_from_item(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
function generate_pill_html(item: CombinedPill): string {
|
export function generate_pill_html(item: CombinedPill): string {
|
||||||
if (item.type === "user_group") {
|
if (item.type === "user_group") {
|
||||||
return render_input_pill({
|
return render_input_pill({
|
||||||
display_value: get_display_value_from_item(item),
|
display_value: get_display_value_from_item(item),
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ let can_mention_group_widget: GroupSettingPillContainer | undefined;
|
|||||||
class UserGroupMembershipError {
|
class UserGroupMembershipError {
|
||||||
report_no_members_to_user_group(): void {
|
report_no_members_to_user_group(): void {
|
||||||
$("#user_group_membership_error").text(
|
$("#user_group_membership_error").text(
|
||||||
$t({defaultMessage: "You cannot create a user group with no members."}),
|
$t({defaultMessage: "You cannot create a user group with no members or subgroups."}),
|
||||||
);
|
);
|
||||||
$("#user_group_membership_error").show();
|
$("#user_group_membership_error").show();
|
||||||
}
|
}
|
||||||
@@ -151,6 +151,7 @@ function create_user_group(): void {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const user_ids = user_group_create_members.get_principals();
|
const user_ids = user_group_create_members.get_principals();
|
||||||
|
const subgroup_ids = user_group_create_members.get_subgroups();
|
||||||
|
|
||||||
assert(can_add_members_group_widget !== undefined);
|
assert(can_add_members_group_widget !== undefined);
|
||||||
const can_add_members_group = settings_components.get_group_setting_widget_value(
|
const can_add_members_group = settings_components.get_group_setting_widget_value(
|
||||||
@@ -177,6 +178,7 @@ function create_user_group(): void {
|
|||||||
name: group_name,
|
name: group_name,
|
||||||
description,
|
description,
|
||||||
members: JSON.stringify(user_ids),
|
members: JSON.stringify(user_ids),
|
||||||
|
subgroups: JSON.stringify(subgroup_ids),
|
||||||
can_add_members_group: JSON.stringify(can_add_members_group),
|
can_add_members_group: JSON.stringify(can_add_members_group),
|
||||||
can_join_group: JSON.stringify(can_join_group),
|
can_join_group: JSON.stringify(can_join_group),
|
||||||
can_leave_group: JSON.stringify(can_leave_group),
|
can_leave_group: JSON.stringify(can_leave_group),
|
||||||
@@ -230,7 +232,8 @@ export function set_up_handlers(): void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const principals = user_group_create_members_data.get_principals();
|
const principals = user_group_create_members_data.get_principals();
|
||||||
if (principals.length === 0) {
|
const subgroups = user_group_create_members_data.get_subgroups();
|
||||||
|
if (principals.length === 0 && subgroups.length === 0) {
|
||||||
user_group_membership_error.report_no_members_to_user_group();
|
user_group_membership_error.report_no_members_to_user_group();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,36 +1,44 @@
|
|||||||
import $ from "jquery";
|
import $ from "jquery";
|
||||||
|
|
||||||
import render_new_user_group_user from "../templates/stream_settings/new_stream_user.hbs";
|
import render_new_user_group_user from "../templates/stream_settings/new_stream_user.hbs";
|
||||||
|
import render_new_user_group_subgroup from "../templates/user_group_settings/new_user_group_subgroup.hbs";
|
||||||
import render_new_user_group_users from "../templates/user_group_settings/new_user_group_users.hbs";
|
import render_new_user_group_users from "../templates/user_group_settings/new_user_group_users.hbs";
|
||||||
|
|
||||||
import * as add_subscribers_pill from "./add_subscribers_pill";
|
import * as add_group_members_pill from "./add_group_members_pill";
|
||||||
import * as ListWidget from "./list_widget";
|
import * as ListWidget from "./list_widget";
|
||||||
import type {ListWidget as ListWidgetType} from "./list_widget";
|
import type {ListWidget as ListWidgetType} from "./list_widget";
|
||||||
import * as people from "./people";
|
import * as people from "./people";
|
||||||
|
import type {User} from "./people";
|
||||||
import {current_user} from "./state_data";
|
import {current_user} from "./state_data";
|
||||||
import type {CombinedPillContainer} from "./typeahead_helper";
|
import type {CombinedPillContainer} from "./typeahead_helper";
|
||||||
|
import * as user_group_components from "./user_group_components";
|
||||||
import * as user_group_create_members_data from "./user_group_create_members_data";
|
import * as user_group_create_members_data from "./user_group_create_members_data";
|
||||||
import * as user_sort from "./user_sort";
|
import type {UserGroup} from "./user_groups";
|
||||||
|
|
||||||
let pill_widget: CombinedPillContainer;
|
let pill_widget: CombinedPillContainer;
|
||||||
let all_users_list_widget: ListWidgetType<number, people.User>;
|
let all_users_list_widget: ListWidgetType<User | UserGroup, User | UserGroup>;
|
||||||
|
|
||||||
export function get_principals(): number[] {
|
export function get_principals(): number[] {
|
||||||
return user_group_create_members_data.get_principals();
|
return user_group_create_members_data.get_principals();
|
||||||
}
|
}
|
||||||
|
|
||||||
function redraw_member_list(): void {
|
export function get_subgroups(): number[] {
|
||||||
all_users_list_widget.replace_list_data(user_group_create_members_data.sorted_user_ids());
|
return user_group_create_members_data.get_subgroups();
|
||||||
}
|
}
|
||||||
|
|
||||||
function add_user_ids(user_ids: number[]): void {
|
function redraw_member_list(): void {
|
||||||
|
all_users_list_widget.replace_list_data(user_group_create_members_data.sorted_members());
|
||||||
|
}
|
||||||
|
|
||||||
|
function add_members(user_ids: number[], subgroup_ids: number[]): void {
|
||||||
user_group_create_members_data.add_user_ids(user_ids);
|
user_group_create_members_data.add_user_ids(user_ids);
|
||||||
|
user_group_create_members_data.add_subgroup_ids(subgroup_ids);
|
||||||
redraw_member_list();
|
redraw_member_list();
|
||||||
}
|
}
|
||||||
|
|
||||||
function add_all_users(): void {
|
function add_all_users(): void {
|
||||||
const user_ids = user_group_create_members_data.get_all_user_ids();
|
const user_ids = user_group_create_members_data.get_all_user_ids();
|
||||||
add_user_ids(user_ids);
|
add_members(user_ids, []);
|
||||||
}
|
}
|
||||||
|
|
||||||
function soft_remove_user_id(user_id: number): void {
|
function soft_remove_user_id(user_id: number): void {
|
||||||
@@ -43,30 +51,40 @@ function undo_soft_remove_user_id(user_id: number): void {
|
|||||||
redraw_member_list();
|
redraw_member_list();
|
||||||
}
|
}
|
||||||
|
|
||||||
export function clear_member_list(): void {
|
function soft_remove_subgroup_id(subgroup_id: number): void {
|
||||||
user_group_create_members_data.initialize_with_current_user();
|
user_group_create_members_data.soft_remove_subgroup_id(subgroup_id);
|
||||||
redraw_member_list();
|
redraw_member_list();
|
||||||
}
|
}
|
||||||
|
|
||||||
function sync_user_ids(user_ids: number[]): void {
|
function undo_soft_remove_subgroup_id(subgroup_id: number): void {
|
||||||
|
user_group_create_members_data.undo_soft_remove_subgroup_id(subgroup_id);
|
||||||
|
redraw_member_list();
|
||||||
|
}
|
||||||
|
|
||||||
|
export function clear_member_list(): void {
|
||||||
|
user_group_create_members_data.initialize_with_current_user();
|
||||||
|
user_group_create_members_data.reset_subgroups_data();
|
||||||
|
redraw_member_list();
|
||||||
|
}
|
||||||
|
|
||||||
|
function sync_members(user_ids: number[], subgroup_ids: number[]): void {
|
||||||
user_group_create_members_data.sync_user_ids(user_ids);
|
user_group_create_members_data.sync_user_ids(user_ids);
|
||||||
|
user_group_create_members_data.sync_subgroup_ids(subgroup_ids);
|
||||||
redraw_member_list();
|
redraw_member_list();
|
||||||
}
|
}
|
||||||
|
|
||||||
function build_pill_widget({$parent_container}: {$parent_container: JQuery}): void {
|
function build_pill_widget({$parent_container}: {$parent_container: JQuery}): void {
|
||||||
const $pill_container = $parent_container.find(".pill-container");
|
const $pill_container = $parent_container.find(".pill-container");
|
||||||
const get_potential_members = user_group_create_members_data.get_potential_members;
|
|
||||||
|
|
||||||
pill_widget = add_subscribers_pill.create_without_add_button({
|
pill_widget = add_group_members_pill.create_without_add_button({
|
||||||
$pill_container,
|
$pill_container,
|
||||||
get_potential_subscribers: get_potential_members,
|
onPillCreateAction: add_members,
|
||||||
onPillCreateAction: add_user_ids,
|
// It is better to sync the current set of user and subgroup ids
|
||||||
// It is better to sync the current set of user ids in the input
|
// in the input instead of removing them from the user_ids_set
|
||||||
// instead of removing user_ids from the user_ids_set, otherwise
|
// and subgroup_id_set, otherwise we'll have to have more complex
|
||||||
// we'll have to have more complex logic of when to remove
|
// logic of when to remove a user and when not to depending upon
|
||||||
// a user and when not to depending upon their group, channel
|
// their channel and individual pills.
|
||||||
// and individual pills.
|
onPillRemoveAction: sync_members,
|
||||||
onPillRemoveAction: sync_user_ids,
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -90,6 +108,20 @@ export function create_handlers($container: JQuery): void {
|
|||||||
const user_id = Number.parseInt($elem.attr("data-user-id")!, 10);
|
const user_id = Number.parseInt($elem.attr("data-user-id")!, 10);
|
||||||
undo_soft_remove_user_id(user_id);
|
undo_soft_remove_user_id(user_id);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$container.on("click", ".remove_potential_subgroup", (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
const $elem = $(e.target);
|
||||||
|
const subgroup_id = Number.parseInt($elem.attr("data-group-id")!, 10);
|
||||||
|
soft_remove_subgroup_id(subgroup_id);
|
||||||
|
});
|
||||||
|
|
||||||
|
$container.on("click", ".undo_soft_removed_potential_subgroup", (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
const $elem = $(e.target);
|
||||||
|
const user_id = Number.parseInt($elem.attr("data-group-id")!, 10);
|
||||||
|
undo_soft_remove_subgroup_id(user_id);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export function build_widgets(): void {
|
export function build_widgets(): void {
|
||||||
@@ -102,33 +134,45 @@ export function build_widgets(): void {
|
|||||||
|
|
||||||
user_group_create_members_data.initialize_with_current_user();
|
user_group_create_members_data.initialize_with_current_user();
|
||||||
const current_user_id = current_user.user_id;
|
const current_user_id = current_user.user_id;
|
||||||
|
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
||||||
|
const initial_members = [people.get_by_user_id(current_user_id)] as (User | UserGroup)[];
|
||||||
|
|
||||||
all_users_list_widget = ListWidget.create($("#create_user_group_members"), [current_user_id], {
|
all_users_list_widget = ListWidget.create($("#create_user_group_members"), initial_members, {
|
||||||
name: "new_user_group_add_users",
|
name: "new_user_group_add_users",
|
||||||
$parent_container: $add_people_container,
|
$parent_container: $add_people_container,
|
||||||
get_item: people.get_by_user_id,
|
get_item: ListWidget.default_get_item,
|
||||||
sort_fields: {
|
sort_fields: {
|
||||||
email: user_sort.sort_email,
|
email: user_group_components.sort_group_member_email,
|
||||||
id: user_sort.sort_user_id,
|
name: user_group_components.sort_group_member_name,
|
||||||
...ListWidget.generic_sort_functions("alphabetic", ["full_name"]),
|
|
||||||
},
|
},
|
||||||
modifier_html(user) {
|
modifier_html(member: User | UserGroup) {
|
||||||
|
if ("user_id" in member) {
|
||||||
|
const item = {
|
||||||
|
email: member.delivery_email,
|
||||||
|
user_id: member.user_id,
|
||||||
|
full_name: member.full_name,
|
||||||
|
is_current_user: member.user_id === current_user_id,
|
||||||
|
img_src: people.small_avatar_url_for_person(member),
|
||||||
|
soft_removed: user_group_create_members_data.user_id_in_soft_remove_list(
|
||||||
|
member.user_id,
|
||||||
|
),
|
||||||
|
};
|
||||||
|
return render_new_user_group_user(item);
|
||||||
|
}
|
||||||
|
|
||||||
const item = {
|
const item = {
|
||||||
email: user.delivery_email,
|
group_id: member.id,
|
||||||
user_id: user.user_id,
|
display_value: member.name,
|
||||||
full_name: user.full_name,
|
soft_removed: user_group_create_members_data.subgroup_id_in_soft_remove_list(
|
||||||
is_current_user: user.user_id === current_user_id,
|
member.id,
|
||||||
img_src: people.small_avatar_url_for_person(user),
|
|
||||||
soft_removed: user_group_create_members_data.user_id_in_soft_remove_list(
|
|
||||||
user.user_id,
|
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
return render_new_user_group_user(item);
|
return render_new_user_group_subgroup(item);
|
||||||
},
|
},
|
||||||
filter: {
|
filter: {
|
||||||
$element: $("#people_to_add_in_group .add-user-list-filter"),
|
$element: $("#people_to_add_in_group .add-user-list-filter"),
|
||||||
predicate(user, search_term) {
|
predicate(member, search_term) {
|
||||||
return people.build_person_matcher(search_term)(user);
|
return user_group_components.build_group_member_matcher(search_term)(member);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
$simplebar_container,
|
$simplebar_container,
|
||||||
|
|||||||
@@ -3,19 +3,34 @@ import _ from "lodash";
|
|||||||
import * as people from "./people";
|
import * as people from "./people";
|
||||||
import type {User} from "./people";
|
import type {User} from "./people";
|
||||||
import {current_user} from "./state_data";
|
import {current_user} from "./state_data";
|
||||||
|
import * as user_group_components from "./user_group_components";
|
||||||
|
import * as user_groups from "./user_groups";
|
||||||
|
import type {UserGroup} from "./user_groups";
|
||||||
|
|
||||||
let user_id_set: Set<number>;
|
let user_id_set: Set<number>;
|
||||||
let soft_remove_user_id_set: Set<number>;
|
let soft_remove_user_id_set: Set<number>;
|
||||||
|
let subgroup_id_set = new Set<number>([]);
|
||||||
|
let soft_remove_subgroup_id_set = new Set<number>([]);
|
||||||
|
|
||||||
export function initialize_with_current_user(): void {
|
export function initialize_with_current_user(): void {
|
||||||
user_id_set = new Set([current_user.user_id]);
|
user_id_set = new Set([current_user.user_id]);
|
||||||
soft_remove_user_id_set = new Set();
|
soft_remove_user_id_set = new Set();
|
||||||
}
|
}
|
||||||
|
|
||||||
export function sorted_user_ids(): number[] {
|
export function reset_subgroups_data(): void {
|
||||||
|
subgroup_id_set = new Set([]);
|
||||||
|
soft_remove_subgroup_id_set = new Set<number>([]);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function sorted_members(): (User | UserGroup)[] {
|
||||||
const users = people.get_users_from_ids([...user_id_set]);
|
const users = people.get_users_from_ids([...user_id_set]);
|
||||||
people.sort_but_pin_current_user_on_top(users);
|
people.sort_but_pin_current_user_on_top(users);
|
||||||
return users.map((user) => user.user_id);
|
|
||||||
|
const subgroups = [...subgroup_id_set]
|
||||||
|
.map((group_id) => user_groups.get_user_group_from_id(group_id))
|
||||||
|
.sort(user_group_components.sort_group_member_name);
|
||||||
|
|
||||||
|
return [...subgroups, ...users];
|
||||||
}
|
}
|
||||||
|
|
||||||
export function get_all_user_ids(): number[] {
|
export function get_all_user_ids(): number[] {
|
||||||
@@ -31,6 +46,10 @@ export function get_principals(): number[] {
|
|||||||
return _.difference([...user_id_set], [...soft_remove_user_id_set]);
|
return _.difference([...user_id_set], [...soft_remove_user_id_set]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function get_subgroups(): number[] {
|
||||||
|
return _.difference([...subgroup_id_set], [...soft_remove_subgroup_id_set]);
|
||||||
|
}
|
||||||
|
|
||||||
export function get_potential_members(): User[] {
|
export function get_potential_members(): User[] {
|
||||||
const potential_members = people.get_realm_users();
|
const potential_members = people.get_realm_users();
|
||||||
return potential_members.filter((user) => !user_id_set.has(user.user_id));
|
return potential_members.filter((user) => !user_id_set.has(user.user_id));
|
||||||
@@ -72,3 +91,30 @@ export function undo_soft_remove_user_id(user_id: number): void {
|
|||||||
export function user_id_in_soft_remove_list(user_id: number): boolean {
|
export function user_id_in_soft_remove_list(user_id: number): boolean {
|
||||||
return soft_remove_user_id_set.has(user_id);
|
return soft_remove_user_id_set.has(user_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function add_subgroup_ids(subgroup_ids: number[]): void {
|
||||||
|
for (const subgroup_id of subgroup_ids) {
|
||||||
|
if (!subgroup_id_set.has(subgroup_id)) {
|
||||||
|
const group = user_groups.get_user_group_from_id(subgroup_id);
|
||||||
|
if (group) {
|
||||||
|
subgroup_id_set.add(subgroup_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function sync_subgroup_ids(subgroup_ids: number[]): void {
|
||||||
|
subgroup_id_set = new Set(subgroup_ids);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function soft_remove_subgroup_id(subgroup_id: number): void {
|
||||||
|
soft_remove_subgroup_id_set.add(subgroup_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function undo_soft_remove_subgroup_id(subgroup_id: number): void {
|
||||||
|
soft_remove_subgroup_id_set.delete(subgroup_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function subgroup_id_in_soft_remove_list(subgroup_id: number): boolean {
|
||||||
|
return soft_remove_subgroup_id_set.has(subgroup_id);
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,12 @@
|
|||||||
|
<tr>
|
||||||
|
<td class="panel_user_list" colspan="2">
|
||||||
|
{{> ../user_group_display_only_pill strikethrough=soft_removed}}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{{#if soft_removed}}
|
||||||
|
<button data-group-id="{{group_id}}" class="undo_soft_removed_potential_subgroup button small rounded white">{{t 'Add' }}</button>
|
||||||
|
{{else}}
|
||||||
|
<button data-group-id="{{group_id}}" class="remove_potential_subgroup button small rounded white">{{t 'Remove' }}</button>
|
||||||
|
{{/if}}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
Reference in New Issue
Block a user