diff --git a/web/src/settings_org.js b/web/src/settings_org.js index 0db8644801..335dbec94c 100644 --- a/web/src/settings_org.js +++ b/web/src/settings_org.js @@ -1,11 +1,13 @@ import $ from "jquery"; import pygments_data from "../generated/pygments_data.json"; +import render_compose_banner from "../templates/compose_banner/compose_banner.hbs"; import render_settings_deactivate_realm_modal from "../templates/confirm_dialog/confirm_deactivate_realm.hbs"; import render_settings_admin_auth_methods_list from "../templates/settings/admin_auth_methods_list.hbs"; import * as blueslip from "./blueslip"; import * as channel from "./channel"; +import * as compose_banner from "./compose_banner"; import {csrf_token} from "./csrf"; import * as dialog_widget from "./dialog_widget"; import * as dropdown_widget from "./dropdown_widget"; @@ -994,6 +996,19 @@ export function check_property_changed(elem, for_realm_default_settings, sub) { return current_val !== proposed_val; } +function switching_to_private(properties_elements, for_realm_default_settings) { + for (const elem of properties_elements) { + const $elem = $(elem); + const property_name = extract_property_name($elem, for_realm_default_settings); + if (property_name !== "stream_privacy") { + continue; + } + const proposed_val = get_input_element_value($elem, "radio-group"); + return proposed_val === "invite-only-public-history" || proposed_val === "invite-only"; + } + return false; +} + export function save_discard_widget_status_handler($subsection, for_realm_default_settings, sub) { $subsection.find(".subsection-failed-status p").hide(); $subsection.find(".save-button").show(); @@ -1005,6 +1020,39 @@ export function save_discard_widget_status_handler($subsection, for_realm_defaul const $save_btn_controls = $subsection.find(".subsection-header .save-button-controls"); const button_state = show_change_process_button ? "unsaved" : "discarded"; change_save_button_state($save_btn_controls, button_state); + + // If this widget is for a stream, and the stream isn't currently private + // but being changed to private, and the user changing this setting isn't + // subscribed, we show a warning that they won't be able to access the + // stream after making it private unless they subscribe. + if (!sub) { + return; + } + if ( + button_state === "unsaved" && + !sub.invite_only && + !sub.subscribed && + switching_to_private(properties_elements, for_realm_default_settings) + ) { + if ($("#stream_permission_settings .stream_privacy_warning").length > 0) { + return; + } + const context = { + banner_type: compose_banner.WARNING, + banner_text: $t({ + defaultMessage: + "Only subscribers can access or join private streams, so you will lose access to this stream if you convert it to a private stream while not subscribed to it.", + }), + button_text: $t({defaultMessage: "Subscribe"}), + classname: "stream_privacy_warning", + stream_id: sub.stream_id, + }; + $("#stream_permission_settings .stream-permissions-warning-banner").append( + render_compose_banner(context), + ); + } else { + $("#stream_permission_settings .stream-permissions-warning-banner").empty(); + } } export function init_dropdown_widgets() { diff --git a/web/src/stream_edit.js b/web/src/stream_edit.js index 618edb9057..fca13c3328 100644 --- a/web/src/stream_edit.js +++ b/web/src/stream_edit.js @@ -466,6 +466,36 @@ export function initialize() { return true; }); + $("#streams_overlay_container").on( + "click", + ".stream-permissions-warning-banner .main-view-banner-close-button", + (event) => { + event.preventDefault(); + $("#stream_permission_settings .stream-permissions-warning-banner").empty(); + }, + ); + + $("#streams_overlay_container").on( + "click", + ".stream-permissions-warning-banner .main-view-banner-action-button", + (event) => { + event.preventDefault(); + event.stopPropagation(); + + const $target = $(event.target).parents(".main-view-banner"); + const stream_id = Number.parseInt($target.attr("data-stream-id"), 10); + // Makes sure we take the correct stream_row. + const $stream_row = $( + `#streams_overlay_container div.stream-row[data-stream-id='${CSS.escape( + stream_id, + )}']`, + ); + const sub = sub_store.get(stream_id); + stream_settings_ui.sub_or_unsub(sub, $stream_row); + $("#stream_permission_settings .stream-permissions-warning-banner").empty(); + }, + ); + function save_stream_info(e) { const sub = get_sub_for_target(e.currentTarget); diff --git a/web/templates/stream_settings/stream_settings.hbs b/web/templates/stream_settings/stream_settings.hbs index cdab10c1a3..7867b5c582 100644 --- a/web/templates/stream_settings/stream_settings.hbs +++ b/web/templates/stream_settings/stream_settings.hbs @@ -52,6 +52,8 @@ {{> ../settings/settings_save_discard_widget section_name="stream-permissions" }} +
+ {{> stream_types stream_post_policy_values=../stream_post_policy_values stream_privacy_policy_values=../stream_privacy_policy_values