user_groups: Add UI to set and update can_mention_group setting.

This commit adds support to set can_mention_group setting
when creating user group and also update the setting for
existing user groups.
This commit is contained in:
Sahil Batra 2023-11-27 16:06:07 +05:30 committed by Tim Abbott
parent db0476622a
commit 2968eb2b04
13 changed files with 192 additions and 11 deletions

View File

@ -259,6 +259,7 @@ EXEMPT_FILES = make_set(
"web/src/url-template.d.ts",
"web/src/user_card_popover.js",
"web/src/user_deactivation_ui.ts",
"web/src/user_group_components.js",
"web/src/user_group_create.js",
"web/src/user_group_create_members.js",
"web/src/user_group_create_members_data.ts",

View File

@ -48,7 +48,7 @@ export function get_realm_time_limits_in_minutes(property) {
return val.toString();
}
export function get_property_value(property_name, for_realm_default_settings, sub) {
export function get_property_value(property_name, for_realm_default_settings, sub, group) {
if (for_realm_default_settings) {
// realm_user_default_settings are stored in a separate object.
if (property_name === "twenty_four_hour_time") {
@ -74,6 +74,10 @@ export function get_property_value(property_name, for_realm_default_settings, su
return sub[property_name];
}
if (group) {
return group[property_name];
}
if (property_name === "realm_org_join_restrictions") {
if (page_params.realm_emails_restricted_to_domains) {
return "only_selected_domain";
@ -240,6 +244,8 @@ export let signup_notifications_stream_widget = null;
export let create_multiuse_invite_group_widget = null;
export let can_remove_subscribers_group_widget = null;
export let can_access_all_users_group_widget = null;
export let can_mention_group_widget = null;
export let new_group_can_mention_group_widget = null;
export function get_widget_for_dropdown_list_settings(property_name) {
switch (property_name) {
@ -255,6 +261,8 @@ export function get_widget_for_dropdown_list_settings(property_name) {
return can_remove_subscribers_group_widget;
case "realm_can_access_all_users_group":
return can_access_all_users_group_widget;
case "can_mention_group":
return can_mention_group_widget;
default:
blueslip.error("No dropdown list widget for property", {property_name});
return null;
@ -285,6 +293,14 @@ export function set_can_access_all_users_group_widget(widget) {
can_access_all_users_group_widget = widget;
}
export function set_can_mention_group_widget(widget) {
can_mention_group_widget = widget;
}
export function set_new_group_can_mention_group_widget(widget) {
new_group_can_mention_group_widget = widget;
}
export function set_dropdown_list_widget_setting_value(property_name, value) {
const widget = get_widget_for_dropdown_list_settings(property_name);
widget.render(value);
@ -475,10 +491,10 @@ function get_time_limit_setting_value($input_elem, for_api_data = true) {
return parse_time_limit($custom_input_elem);
}
export function check_property_changed(elem, for_realm_default_settings, sub) {
export function check_property_changed(elem, for_realm_default_settings, sub, group) {
const $elem = $(elem);
const property_name = extract_property_name($elem, for_realm_default_settings);
let current_val = get_property_value(property_name, for_realm_default_settings, sub);
let current_val = get_property_value(property_name, for_realm_default_settings, sub, group);
let proposed_val;
switch (property_name) {
@ -493,6 +509,7 @@ export function check_property_changed(elem, for_realm_default_settings, sub) {
case "realm_default_code_block_language":
case "can_remove_subscribers_group":
case "realm_create_multiuse_invite_group":
case "can_mention_group":
proposed_val = get_dropdown_list_widget_setting_value($elem);
break;
case "email_notifications_batching_period_seconds":
@ -545,12 +562,17 @@ function switching_to_private(properties_elements, for_realm_default_settings) {
return false;
}
export function save_discard_widget_status_handler($subsection, for_realm_default_settings, sub) {
export function save_discard_widget_status_handler(
$subsection,
for_realm_default_settings,
sub,
group,
) {
$subsection.find(".subsection-failed-status p").hide();
$subsection.find(".save-button").show();
const properties_elements = get_subsection_property_elements($subsection);
const show_change_process_button = properties_elements.some((elem) =>
check_property_changed(elem, for_realm_default_settings, sub),
check_property_changed(elem, for_realm_default_settings, sub, group),
);
const $save_btn_controls = $subsection.find(".subsection-header .save-button-controls");

View File

@ -447,7 +447,7 @@ function update_dependent_subsettings(property_name) {
}
}
export function discard_property_element_changes(elem, for_realm_default_settings, sub) {
export function discard_property_element_changes(elem, for_realm_default_settings, sub, group) {
const $elem = $(elem);
const property_name = settings_components.extract_property_name(
$elem,
@ -457,6 +457,7 @@ export function discard_property_element_changes(elem, for_realm_default_setting
property_name,
for_realm_default_settings,
sub,
group,
);
switch (property_name) {
@ -478,6 +479,7 @@ export function discard_property_element_changes(elem, for_realm_default_setting
case "can_remove_subscribers_group":
case "realm_create_multiuse_invite_group":
case "realm_can_access_all_users_group":
case "can_mention_group":
settings_components.set_dropdown_list_widget_setting_value(
property_name,
property_value,
@ -767,19 +769,24 @@ export function init_dropdown_widgets() {
can_access_all_users_group_widget.setup();
}
export function populate_data_for_request(subsection, for_realm_default_settings, sub) {
export function populate_data_for_request(subsection, for_realm_default_settings, sub, group) {
let data = {};
const properties_elements = settings_components.get_subsection_property_elements(subsection);
for (const input_elem of properties_elements) {
const $input_elem = $(input_elem);
if (
settings_components.check_property_changed($input_elem, for_realm_default_settings, sub)
settings_components.check_property_changed(
$input_elem,
for_realm_default_settings,
sub,
group,
)
) {
const input_value = settings_components.get_input_element_value($input_elem);
if (input_value !== undefined) {
let property_name;
if (for_realm_default_settings || sub) {
if (for_realm_default_settings || sub || group) {
property_name = settings_components.extract_property_name(
$input_elem,
for_realm_default_settings,

View File

@ -159,6 +159,7 @@ export type UserGroupUpdateEvent = {
data: {
name?: string;
description?: string;
can_mention_group?: number;
};
};

View File

@ -0,0 +1,55 @@
import $ from "jquery";
import * as dropdown_widget from "./dropdown_widget";
import * as settings_components from "./settings_components";
import * as user_groups from "./user_groups";
export function setup_permissions_dropdown(group, for_group_creation) {
let widget_name;
let default_id;
if (for_group_creation) {
widget_name = "new_group_can_mention_group";
default_id = user_groups.get_user_group_from_name("role:everyone").id;
} else {
widget_name = "can_mention_group";
default_id = group.can_mention_group;
}
const can_mention_group_widget = new dropdown_widget.DropdownWidget({
widget_name,
get_options: () =>
user_groups.get_realm_user_groups_for_dropdown_list_widget(
"can_mention_group",
"group",
),
item_click_callback(event, dropdown) {
dropdown.hide();
event.preventDefault();
event.stopPropagation();
can_mention_group_widget.render();
if (!for_group_creation) {
settings_components.save_discard_widget_status_handler(
$("#group_permission_settings"),
false,
undefined,
group,
);
}
},
$events_container: $("#groups_overlay .group-permissions"),
tippy_props: {
placement: "bottom-start",
},
default_id,
unique_id_type: dropdown_widget.DATA_TYPES.NUMBER,
on_mount_callback(dropdown) {
$(dropdown.popper).css("min-width", "300px");
},
});
if (for_group_creation) {
settings_components.set_new_group_can_mention_group_widget(can_mention_group_widget);
} else {
settings_components.set_can_mention_group_widget(can_mention_group_widget);
}
can_mention_group_widget.setup();
}

View File

@ -4,7 +4,9 @@ import * as channel from "./channel";
import {$t, $t_html} from "./i18n";
import * as keydown_util from "./keydown_util";
import * as loading from "./loading";
import * as settings_components from "./settings_components";
import * as ui_report from "./ui_report";
import * as user_group_components from "./user_group_components";
import * as user_group_create_members from "./user_group_create_members";
import * as user_group_create_members_data from "./user_group_create_members_data";
import * as user_groups from "./user_groups";
@ -122,6 +124,10 @@ function create_user_group() {
const user_ids = user_group_create_members.get_principals();
data.members = JSON.stringify(user_ids);
data.can_mention_group = Number.parseInt(
settings_components.new_group_can_mention_group_widget.value(),
10,
);
loading.make_indicator($("#user_group_creating_indicator"), {
text: $t({defaultMessage: "Creating group..."}),
});
@ -192,4 +198,6 @@ export function set_up_handlers() {
e.preventDefault();
}
});
user_group_components.setup_permissions_dropdown(undefined, true);
}

View File

@ -20,9 +20,12 @@ import * as overlays from "./overlays";
import {page_params} from "./page_params";
import * as people from "./people";
import * as scroll_util from "./scroll_util";
import * as settings_components from "./settings_components";
import * as settings_data from "./settings_data";
import * as settings_org from "./settings_org";
import * as stream_ui_updates from "./stream_ui_updates";
import * as ui_report from "./ui_report";
import * as user_group_components from "./user_group_components";
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";
@ -241,6 +244,13 @@ export function update_settings_pane(group) {
const $edit_container = get_edit_container(group);
$edit_container.find(".group-name").text(group.name);
$edit_container.find(".group-description").text(group.description);
settings_org.discard_property_element_changes(
$("#id_can_mention_group"),
false,
undefined,
group,
);
}
function update_toggler_for_group_setting() {
@ -267,6 +277,9 @@ export function show_settings_for(group) {
$edit_container.show();
show_membership_settings(group);
user_group_components.setup_permissions_dropdown(group, false);
$edit_container.find("button").prop("disabled", !settings_data.can_edit_user_group(group.id));
}
export function setup_group_settings(group) {
@ -879,6 +892,48 @@ export function initialize() {
const $group_row = row_for_group_id(user_group_id);
add_or_remove_from_group(user_group, $group_row);
});
$("#groups_overlay_container").on(
"click",
".subsection-header .subsection-changes-save button",
(e) => {
e.preventDefault();
e.stopPropagation();
const $save_button = $(e.currentTarget);
const $subsection_elem = $save_button.closest(".settings-subsection-parent");
const group_id = $save_button.closest(".user_group_settings_wrapper").data("group-id");
const group = user_groups.get_user_group_from_id(group_id);
const data = settings_org.populate_data_for_request(
$subsection_elem,
false,
undefined,
group,
);
const url = "/json/user_groups/" + group_id;
settings_org.save_organization_settings(data, $save_button, url);
},
);
$("#groups_overlay_container").on(
"click",
".subsection-header .subsection-changes-discard button",
(e) => {
e.preventDefault();
e.stopPropagation();
const group_id = $(e.target).closest(".user_group_settings_wrapper").data("group-id");
const group = user_groups.get_user_group_from_id(group_id);
const $subsection = $(e.target).closest(".settings-subsection-parent");
for (const elem of settings_components.get_subsection_property_elements($subsection)) {
settings_org.discard_property_element_changes(elem, false, undefined, group);
}
const $save_btn_controls = $(e.target).closest(".save-button-controls");
settings_components.change_save_button_state($save_btn_controls, "discarded");
},
);
}
export function launch(section) {

View File

@ -78,6 +78,12 @@ export function update(event: UserGroupUpdateEvent): void {
user_group_name_dict.delete(group.name);
user_group_name_dict.set(group.name, group);
}
if (event.data.can_mention_group !== undefined) {
group.can_mention_group = event.data.can_mention_group;
user_group_name_dict.delete(group.name);
user_group_name_dict.set(group.name, group);
}
}
export function get_user_group_from_name(name: string): UserGroup | undefined {

View File

@ -835,7 +835,8 @@ div.overlay {
}
#stream_settings .save-button-controls,
#settings_page .save-button-controls {
#settings_page .save-button-controls,
#user_group_settings .save-button-controls {
display: inline;
margin-left: 15px;

View File

@ -1008,7 +1008,8 @@ div.settings-radio-input-parent {
}
.stream-permissions,
.stream-creation-body {
.stream-creation-body,
.group-permissions {
.input-group {
margin-bottom: 10px;

View File

@ -0,0 +1,4 @@
{{> ../dropdown_widget_with_label
widget_name=can_mention_group_widget_name
label=(t 'Who can mention this group?')
value_type="number"}}

View File

@ -20,6 +20,16 @@
<input type="text" name="user_group_description" id="create_user_group_description" class="settings_text_input"
placeholder="{{t 'User group description' }}" value="" autocomplete="off" />
</section>
<section class="block">
<div class="group-permissions settings-subsection-parent" id="new_group_permission_settings">
<div class="subsection-header">
<h3 class="user_group_setting_subsection_title">{{t "Group permissions" }}
</h3>
</div>
{{> group_permissions can_mention_group_widget_name="new_group_can_mention_group"}}
</div>
</section>
<section class="block">
<label for="people_to_add_in_group">
<h4 class="user_group_setting_subsection_title">{{t "Choose members" }}</h4>

View File

@ -35,6 +35,16 @@
{{group.description}}
</span>
</div>
<div class="group-permissions settings-subsection-parent" id="group_permission_settings">
<div class="subsection-header">
<h3 class="user_group_setting_subsection_title">{{t "Group permissions" }}
</h3>
{{> ../settings/settings_save_discard_widget section_name="group-permissions" }}
</div>
{{> group_permissions can_mention_group_widget_name="can_mention_group"}}
</div>
</div>
<div class="group_member_settings group_setting_section">