stream settings: Always show stream settings.

We now show the stream permission settings - stream privacy,
stream post policy and stream message retentions setting,
always in the "General" section of stream settings instead
of showing it in the modal. The setting elements are
disabled for users who cannot change them.

Some important changes are -
- Add proper classes and IDs to the elements such that
code in settings_org.js can be used to set and change these
settings.
- Code in "settings_org.js" is updated to be able to set
stream message retention setting while rendering the page.
- Added enable_or_disable_permission_settings_in_edit_panel
function in stream_ui_updates.js (since that will also be
used in live updating code) to disable the setting elements
if required.
- We also update update_web_public_stream_privacy_option_state
function such that we can correctly enable/disable web-public
option in stream edit panel based on permissions.
- Added code for save-discard widget in stream_settings.hbs in
this commit but code to implement the correct behavior of it
will be added in further commits.

Fixes part of #19519.
This commit is contained in:
Julia Bichler 2022-10-18 09:03:09 +00:00 committed by Tim Abbott
parent e64c1948ed
commit b871ffe712
7 changed files with 114 additions and 51 deletions

View File

@ -135,7 +135,7 @@ export function get_realm_time_limits_in_minutes(property) {
return val.toString(); return val.toString();
} }
function get_property_value(property_name, for_realm_default_settings) { function get_property_value(property_name, for_realm_default_settings, sub) {
if (for_realm_default_settings) { if (for_realm_default_settings) {
// realm_user_default_settings are stored in a separate object. // realm_user_default_settings are stored in a separate object.
if (property_name === "twenty_four_hour_time") { if (property_name === "twenty_four_hour_time") {
@ -150,6 +150,10 @@ function get_property_value(property_name, for_realm_default_settings) {
return realm_user_settings_defaults[property_name]; return realm_user_settings_defaults[property_name];
} }
if (sub) {
return sub[property_name];
}
if (property_name === "realm_waiting_period_setting") { if (property_name === "realm_waiting_period_setting") {
if (page_params.realm_waiting_period_threshold === 0) { if (page_params.realm_waiting_period_threshold === 0) {
return "none"; return "none";
@ -363,12 +367,19 @@ function get_dropdown_value_for_message_retention_setting(setting_value) {
return "unlimited"; return "unlimited";
} }
if (setting_value === null) {
return "realm_default";
}
return "custom_period"; return "custom_period";
} }
function set_message_retention_setting_dropdown() { export function set_message_retention_setting_dropdown(sub) {
const property_name = "realm_message_retention_days"; let property_name = "realm_message_retention_days";
const setting_value = get_property_value(property_name, false); if (sub !== undefined) {
property_name = "message_retention_days";
}
const setting_value = get_property_value(property_name, false, sub);
const dropdown_val = get_dropdown_value_for_message_retention_setting(setting_value); const dropdown_val = get_dropdown_value_for_message_retention_setting(setting_value);
const $dropdown_elem = $(`#id_${CSS.escape(property_name)}`); const $dropdown_elem = $(`#id_${CSS.escape(property_name)}`);

View File

@ -21,6 +21,7 @@ import * as keydown_util from "./keydown_util";
import * as narrow_state from "./narrow_state"; import * as narrow_state from "./narrow_state";
import {page_params} from "./page_params"; import {page_params} from "./page_params";
import * as settings_config from "./settings_config"; import * as settings_config from "./settings_config";
import * as settings_org from "./settings_org";
import * as settings_ui from "./settings_ui"; import * as settings_ui from "./settings_ui";
import * as stream_color from "./stream_color"; import * as stream_color from "./stream_color";
import * as stream_data from "./stream_data"; import * as stream_data from "./stream_data";
@ -258,7 +259,13 @@ export function show_settings_for(node) {
notification_settings, notification_settings,
other_settings, other_settings,
stream_post_policy_values: stream_data.stream_post_policy_values, stream_post_policy_values: stream_data.stream_post_policy_values,
message_retention_text: get_retention_policy_text_for_subscription_type(sub), stream_privacy_policy_values: stream_data.stream_privacy_policy_values,
stream_privacy_policy: stream_data.get_stream_privacy_policy(stream_id),
zulip_plan_is_not_limited: page_params.zulip_plan_is_not_limited,
upgrade_text_for_wide_organization_logo:
page_params.upgrade_text_for_wide_organization_logo,
is_admin: page_params.is_admin,
org_level_message_retention_setting: get_display_text_for_realm_message_retention_setting(),
}); });
ui.get_content_element($("#stream_settings")).html(html); ui.get_content_element($("#stream_settings")).html(html);
@ -273,6 +280,8 @@ export function show_settings_for(node) {
$edit_container.addClass("show"); $edit_container.addClass("show");
show_subscription_settings(sub); show_subscription_settings(sub);
settings_org.set_message_retention_setting_dropdown(sub);
stream_ui_updates.enable_or_disable_permission_settings_in_edit_panel(sub);
} }
export function setup_stream_settings(node) { export function setup_stream_settings(node) {
@ -761,4 +770,12 @@ export function initialize() {
open_edit_panel_for_row(this); open_edit_panel_for_row(this);
} }
}); });
$("#manage_streams_container").on("change", ".stream_message_retention_setting", (e) => {
const message_retention_setting_dropdown_value = e.target.value;
settings_org.change_element_block_display_property(
"stream_message_retention_custom_input",
message_retention_setting_dropdown_value === "custom_period",
);
});
} }

View File

@ -1015,12 +1015,27 @@ export function update_web_public_stream_privacy_option_state($container) {
const $web_public_stream_elem = $container.find( const $web_public_stream_elem = $container.find(
`input[value='${CSS.escape(stream_data.stream_privacy_policy_values.web_public.code)}']`, `input[value='${CSS.escape(stream_data.stream_privacy_policy_values.web_public.code)}']`,
); );
const for_stream_edit_panel = $container.attr("id") === "stream_permission_settings";
if (for_stream_edit_panel) {
const stream_id = Number.parseInt(
$container.closest(".subscription_settings.show").attr("data-stream-id"),
10,
);
const sub = sub_store.get(stream_id);
if (!stream_data.can_change_permissions(sub)) {
// We do not want to enable the already disabled web-public option
// in stream-edit panel if user is not allowed to change stream
// privacy at all.
return;
}
}
if ( if (
!page_params.server_web_public_streams_enabled || !page_params.server_web_public_streams_enabled ||
!page_params.realm_enable_spectator_access !page_params.realm_enable_spectator_access
) { ) {
const for_change_privacy_modal = $container.attr("id") === "stream_privacy_modal"; if (for_stream_edit_panel && $web_public_stream_elem.is(":checked")) {
if (for_change_privacy_modal && $web_public_stream_elem.is(":checked")) {
// We do not hide web-public option in the "Change privacy" modal if // We do not hide web-public option in the "Change privacy" modal if
// stream is web-public already. The option is disabled in this case. // stream is web-public already. The option is disabled in this case.
$web_public_stream_elem.prop("disabled", true); $web_public_stream_elem.prop("disabled", true);
@ -1083,15 +1098,15 @@ export function update_stream_privacy_choices(policy) {
if (!overlays.streams_open()) { if (!overlays.streams_open()) {
return; return;
} }
const change_privacy_modal_opened = $("#stream_privacy_modal").is(":visible"); const stream_edit_panel_opened = $("#stream_permission_settings").is(":visible");
const stream_creation_form_opened = $("#stream-creation").is(":visible"); const stream_creation_form_opened = $("#stream-creation").is(":visible");
if (!change_privacy_modal_opened && !stream_creation_form_opened) { if (!stream_edit_panel_opened && !stream_creation_form_opened) {
return; return;
} }
let $container = $("#stream-creation"); let $container = $("#stream-creation");
if (change_privacy_modal_opened) { if (stream_edit_panel_opened) {
$container = $("#stream_privacy_modal"); $container = $("#stream_permission_settings");
} }
if (policy === "create_private_stream_policy") { if (policy === "create_private_stream_policy") {

View File

@ -136,6 +136,32 @@ export function update_change_stream_privacy_settings(sub) {
} }
} }
export function enable_or_disable_permission_settings_in_edit_panel(sub) {
const $stream_settings = stream_settings_containers.get_edit_container(sub);
const $general_settings_container = $stream_settings.find($("#stream_permission_settings"));
$general_settings_container
.find("input, select")
.prop("disabled", !sub.can_change_stream_permissions);
if (!sub.can_change_stream_permissions) {
return;
}
const disable_message_retention_setting =
!page_params.zulip_plan_is_not_limited || !page_params.is_owner;
$stream_settings
.find(".stream_message_retention_setting")
.prop("disabled", disable_message_retention_setting);
$stream_settings
.find(".message-retention-setting-custom-input")
.prop("disabled", disable_message_retention_setting);
stream_settings_ui.update_web_public_stream_privacy_option_state(
$("#stream_permission_settings"),
);
}
export function update_stream_privacy_icon_in_settings(sub) { export function update_stream_privacy_icon_in_settings(sub) {
if (!hash_util.is_editing_stream(sub.stream_id)) { if (!hash_util.is_editing_stream(sub.stream_id)) {
return; return;

View File

@ -979,6 +979,7 @@ div.settings-radio-input-parent {
float: left; float: left;
width: auto; width: auto;
cursor: pointer; cursor: pointer;
margin: 3.5px 0 1px;
&:focus { &:focus {
outline: 1px dotted hsl(0, 0%, 20%); outline: 1px dotted hsl(0, 0%, 20%);
@ -992,7 +993,7 @@ div.settings-radio-input-parent {
} }
} }
#stream_privacy_modal, .stream-permissions,
.stream-creation-body { .stream-creation-body {
.input-group { .input-group {
margin-bottom: 10px; margin-bottom: 10px;
@ -1016,15 +1017,6 @@ div.settings-radio-input-parent {
} }
} }
.stream-creation-body input[type="radio"] {
margin: 3.5px 0 1px;
}
/* we have this 2px difference due to the font size being larger in the modal */
#stream_privacy_modal input[type="radio"] {
margin: 5.5px 0 1px;
}
#change_user_group_description, #change_user_group_description,
#change_stream_description { #change_stream_description {
width: 100%; width: 100%;
@ -1033,7 +1025,7 @@ div.settings-radio-input-parent {
box-sizing: border-box; box-sizing: border-box;
} }
#stream_privacy_modal .stream-message-retention-days-input input[type="text"] { .stream-permissions .stream-message-retention-days-input input[type="text"] {
border-radius: 5px; border-radius: 5px;
box-shadow: none; box-shadow: none;
margin: 0; margin: 0;

View File

@ -45,23 +45,21 @@
rendered_description=rendered_description rendered_description=rendered_description
}} }}
</div> </div>
<div class="stream_setting_subsection_header"> <div class="stream-permissions settings-subsection-parent" id="stream_permission_settings">
<h3 class="stream_setting_subsection_title"> <div class="subsection-header">
{{t "Stream permissions" }} <h3 class="stream_setting_subsection_title">{{t "Stream permissions" }}
</h3> </h3>
<div class="stream_permission_change_info alert-notification"></div> {{> ../settings/settings_save_discard_widget section_name="stream-permissions" }}
<div class="button-group">
<button class="change-stream-privacy button rounded small btn-warning tippy-zulip-tooltip" data-tippy-content="{{t 'Change stream permissions' }}" {{#unless can_change_stream_permissions}}style="display:none"{{/unless}}>
<i class="fa fa-pencil" aria-hidden="true"></i>
</button>
</div>
</div>
<div class="subscription-type">
<div class="subscription-type-text">
{{> stream_permission_description
stream_post_policy_values=../stream_post_policy_values
message_retention_text=../message_retention_text}}
</div> </div>
{{> stream_types
stream_post_policy_values=../stream_post_policy_values
stream_privacy_policy_values=../stream_privacy_policy_values
stream_privacy_policy=../stream_privacy_policy
zulip_plan_is_not_limited=../zulip_plan_is_not_limited
upgrade_text_for_wide_organization_logo=../upgrade_text_for_wide_organization_logo
org_level_message_retention_setting=../org_level_message_retention_setting
is_stream_edit=true }}
</div> </div>
{{/with}} {{/with}}
<div class="stream-email-box" {{#unless sub.email_address}}style="display: none;"{{/unless}}> <div class="stream-email-box" {{#unless sub.email_address}}style="display: none;"{{/unless}}>

View File

@ -3,14 +3,17 @@
<label>{{t 'Who can access the stream?'}} <label>{{t 'Who can access the stream?'}}
{{> ../help_link_widget link="/help/stream-permissions" }} {{> ../help_link_widget link="/help/stream-permissions" }}
</label> </label>
{{#each stream_privacy_policy_values}}
<div class="settings-radio-input-parent"> <div class="stream-privacy_choices prop-element" id="id_stream_privacy" data-setting-widget-type="radio-group" data-setting-choice-type="string">
<label class="radio"> {{#each stream_privacy_policy_values}}
<input type="radio" name="privacy" value="{{ this.code }}" {{#if (eq this.code ../stream_privacy_policy) }}checked{{/if}} /> <div class="settings-radio-input-parent">
<b>{{ this.name }}:</b> {{ this.description }} <label class="radio">
</label> <input type="radio" name="privacy" value="{{ this.code }}" {{#if (eq this.code ../stream_privacy_policy) }}checked{{/if}} />
</div> <b>{{ this.name }}:</b> {{ this.description }}
{{/each}} </label>
</div>
{{/each}}
</div>
</div> </div>
{{#if ask_to_announce_stream}} {{#if ask_to_announce_stream}}
@ -28,7 +31,7 @@
<label class="dropdown-title">{{t 'Who can post to the stream?'}} <label class="dropdown-title">{{t 'Who can post to the stream?'}}
{{> ../help_link_widget link="/help/stream-sending-policy" }} {{> ../help_link_widget link="/help/stream-sending-policy" }}
</label> </label>
<select name="stream-post-policy" class="stream_post_policy_setting prop-element"> <select name="stream-post-policy" class="stream_post_policy_setting prop-element" id="id_stream_post_policy" data-setting-widget-type="number">
{{#each stream_post_policy_values}} {{#each stream_post_policy_values}}
<option value="{{this.code}}" {{#if (eq this.code ../stream_post_policy) }}selected{{/if}}> <option value="{{this.code}}" {{#if (eq this.code ../stream_post_policy) }}selected{{/if}}>
{{ this.description}} {{ this.description}}
@ -47,7 +50,8 @@
</label> </label>
<select name="stream_message_retention_setting" <select name="stream_message_retention_setting"
class="stream_message_retention_setting prop-element" class="stream_message_retention_setting prop-element"
{{#if disable_message_retention_setting}}disabled{{/if}}> id="id_message_retention_days"
data-setting-widget-type="message-retention-setting">
<option value="realm_default">{{#tr}}Use organization level settings {org_level_message_retention_setting}{{/tr}}</option> <option value="realm_default">{{#tr}}Use organization level settings {org_level_message_retention_setting}{{/tr}}</option>
<option value="unlimited">{{t 'Retain forever' }}</option> <option value="unlimited">{{t 'Retain forever' }}</option>
<option value="custom_period">{{t 'Custom' }}</option> <option value="custom_period">{{t 'Custom' }}</option>
@ -59,9 +63,9 @@
</label> </label>
<input type="text" autocomplete="off" <input type="text" autocomplete="off"
name="stream-message-retention-days" name="stream-message-retention-days"
class="stream-message-retention-days" class="stream-message-retention-days message-retention-setting-custom-input"
value="{{ stream_message_retention_days }}" id="stream_message_retention_custom_input"
{{#if disable_message_retention_setting}}disabled{{/if}}/> value="{{ stream_message_retention_days }}"/>
</div> </div>
</div> </div>
</div> </div>