diff --git a/web/src/compose_recipient.ts b/web/src/compose_recipient.ts index f60d205cb6..0f6b4c3fea 100644 --- a/web/src/compose_recipient.ts +++ b/web/src/compose_recipient.ts @@ -259,8 +259,7 @@ function get_options_for_recipient_widget(): Option[] { name: $t({defaultMessage: "Direct message"}), }; - const {name} = user_groups.get_user_group_from_id(realm.realm_direct_message_permission_group); - if (name !== "role:nobody") { + if (!user_groups.is_empty_group(realm.realm_direct_message_permission_group)) { options.unshift(direct_messages_option); } else { options.push(direct_messages_option); diff --git a/web/src/compose_validate.ts b/web/src/compose_validate.ts index ebd76f6371..683c40d4cd 100644 --- a/web/src/compose_validate.ts +++ b/web/src/compose_validate.ts @@ -114,10 +114,7 @@ export function needs_subscribe_warning(user_id: number, stream_id: number): boo export function check_dm_permissions_and_get_error_string(user_ids_string: string): string { if (!people.user_can_direct_message(user_ids_string)) { - const {name} = user_groups.get_user_group_from_id( - realm.realm_direct_message_permission_group, - ); - if (name === "role:nobody") { + if (user_groups.is_empty_group(realm.realm_direct_message_permission_group)) { return $t({ defaultMessage: "Direct messages are disabled in this organization.", }); diff --git a/web/src/settings_org.js b/web/src/settings_org.js index 3fa4c88ba9..2712a4aa40 100644 --- a/web/src/settings_org.js +++ b/web/src/settings_org.js @@ -370,7 +370,7 @@ function set_create_web_public_stream_dropdown_visibility() { } export function check_disable_direct_message_initiator_group_dropdown(current_value) { - if (current_value === user_groups.get_user_group_from_name("role:nobody").id) { + if (user_groups.is_empty_group(current_value)) { $("#realm_direct_message_initiator_group_widget").prop("disabled", true); } else { $("#realm_direct_message_initiator_group_widget").prop("disabled", false); diff --git a/web/src/user_groups.ts b/web/src/user_groups.ts index bce7e228c3..aca722584d 100644 --- a/web/src/user_groups.ts +++ b/web/src/user_groups.ts @@ -178,6 +178,37 @@ export function is_user_group( return item.members !== undefined; } +export function is_empty_group(user_group_id: number): boolean { + const user_group = user_group_by_id_dict.get(user_group_id); + if (user_group === undefined) { + blueslip.error("Could not find user group", {user_group_id}); + return false; + } + if (user_group.members.size > 0) { + return false; + } + + // Check if all the recursive subgroups are empty. + // Correctness of this algorithm relying on the ES6 Set + // implementation having the property that a `for of` loop will + // visit all items that are added to the set during the loop. + const subgroup_ids = new Set(user_group.direct_subgroup_ids); + for (const subgroup_id of subgroup_ids) { + const subgroup = user_group_by_id_dict.get(subgroup_id); + if (subgroup === undefined) { + blueslip.error("Could not find subgroup", {subgroup_id}); + return false; + } + if (subgroup.members.size > 0) { + return false; + } + for (const direct_subgroup_id of subgroup.direct_subgroup_ids) { + subgroup_ids.add(direct_subgroup_id); + } + } + return true; +} + export function get_user_groups_of_user(user_id: number): UserGroup[] { const user_groups_realm = get_realm_user_groups(); const groups_of_user = user_groups_realm.filter((group) =>