stream-settings: Live update visibility of folder dropdown.

An error was raised where we tried to live update the folder name
in folder dropdown even when there was no dropdown visible
to the non-admin user in settings page. This was because
"There are no channel folders configured in this organization."
text was shown even when a folder was recently created in the
realm as we did not live update the visibility of dropdown on
creating or archiving a folder.

This commit fixes the bug by live-updating the visibility
of folder dropdown when creating or archiving a folder.
This commit is contained in:
Sahil Batra
2025-08-14 09:28:40 +05:30
committed by Tim Abbott
parent 331d210dac
commit 0a8238b993
7 changed files with 52 additions and 14 deletions

View File

@@ -124,6 +124,7 @@ export function dispatch_normal_event(event) {
channel_folders.add(event.channel_folder); channel_folders.add(event.channel_folder);
inbox_ui.complete_rerender(); inbox_ui.complete_rerender();
settings_folders.populate_channel_folders(); settings_folders.populate_channel_folders();
stream_ui_updates.update_folder_dropdown_visibility();
break; break;
} }
case "update": case "update":
@@ -138,6 +139,7 @@ export function dispatch_normal_event(event) {
stream_settings_ui.reset_dropdown_set_to_archived_folder( stream_settings_ui.reset_dropdown_set_to_archived_folder(
event.channel_folder_id, event.channel_folder_id,
); );
stream_ui_updates.update_folder_dropdown_visibility();
} }
settings_folders.update_folder_row(event); settings_folders.update_folder_row(event);
break; break;

View File

@@ -17,7 +17,6 @@ import * as blueslip from "./blueslip.ts";
import type {Bot} from "./bot_data.ts"; import type {Bot} from "./bot_data.ts";
import * as browser_history from "./browser_history.ts"; import * as browser_history from "./browser_history.ts";
import * as channel from "./channel.ts"; import * as channel from "./channel.ts";
import * as channel_folders from "./channel_folders.ts";
import * as channel_folders_ui from "./channel_folders_ui.ts"; import * as channel_folders_ui from "./channel_folders_ui.ts";
import * as confirm_dialog from "./confirm_dialog.ts"; import * as confirm_dialog from "./confirm_dialog.ts";
import {show_copied_confirmation} from "./copied_tooltip.ts"; import {show_copied_confirmation} from "./copied_tooltip.ts";
@@ -257,7 +256,6 @@ export function show_settings_for(node: HTMLElement): void {
other_settings.push(setting); other_settings.push(setting);
return false; return false;
}); });
const realm_has_channel_folders = channel_folders.get_active_folder_ids().size > 0;
const html = render_stream_settings({ const html = render_stream_settings({
sub, sub,
@@ -277,7 +275,6 @@ export function show_settings_for(node: HTMLElement): void {
group_setting_labels: settings_config.all_group_setting_labels.stream, group_setting_labels: settings_config.all_group_setting_labels.stream,
has_billing_access: settings_data.user_has_billing_access(), has_billing_access: settings_data.user_has_billing_access(),
empty_string_topic_display_name: util.get_final_topic_display_name(""), empty_string_topic_display_name: util.get_final_topic_display_name(""),
realm_has_channel_folders,
}); });
scroll_util.get_content_element($("#stream_settings")).html(html); scroll_util.get_content_element($("#stream_settings")).html(html);
@@ -299,6 +296,7 @@ export function show_settings_for(node: HTMLElement): void {
setup_group_setting_widgets(slim_sub); setup_group_setting_widgets(slim_sub);
stream_ui_updates.update_can_subscribe_group_label($edit_container); stream_ui_updates.update_can_subscribe_group_label($edit_container);
stream_settings_components.set_up_folder_dropdown_widget(sub); stream_settings_components.set_up_folder_dropdown_widget(sub);
stream_ui_updates.set_folder_dropdown_visibility($("#stream_settings"));
$("#channels_overlay_container").on( $("#channels_overlay_container").on(
"click", "click",

View File

@@ -11,7 +11,6 @@ import render_stream_settings_overlay from "../templates/stream_settings/stream_
import type {Banner} from "./banners.ts"; import type {Banner} from "./banners.ts";
import * as blueslip from "./blueslip.ts"; import * as blueslip from "./blueslip.ts";
import * as browser_history from "./browser_history.ts"; import * as browser_history from "./browser_history.ts";
import * as channel_folders from "./channel_folders.ts";
import * as components from "./components.ts"; import * as components from "./components.ts";
import type {Toggle} from "./components.ts"; import type {Toggle} from "./components.ts";
import * as compose_banner from "./compose_banner.ts"; import * as compose_banner from "./compose_banner.ts";
@@ -932,7 +931,6 @@ function setup_page(callback: () => void): void {
new_stream_announcements_stream, new_stream_announcements_stream,
); );
const realm_has_archived_channels = stream_data.get_archived_subs().length > 0; const realm_has_archived_channels = stream_data.get_archived_subs().length > 0;
const realm_has_channel_folders = channel_folders.get_active_folder_ids().size > 0;
const template_data = { const template_data = {
new_stream_announcements_stream_sub, new_stream_announcements_stream_sub,
@@ -962,7 +960,6 @@ function setup_page(callback: () => void): void {
has_billing_access: settings_data.user_has_billing_access(), has_billing_access: settings_data.user_has_billing_access(),
is_admin: current_user.is_admin, is_admin: current_user.is_admin,
empty_string_topic_display_name: util.get_final_topic_display_name(""), empty_string_topic_display_name: util.get_final_topic_display_name(""),
realm_has_channel_folders,
}; };
const rendered = render_stream_settings_overlay(template_data); const rendered = render_stream_settings_overlay(template_data);
@@ -974,6 +971,8 @@ function setup_page(callback: () => void): void {
redraw_left_panel(); redraw_left_panel();
stream_create.set_up_handlers(); stream_create.set_up_handlers();
stream_ui_updates.set_folder_dropdown_visibility($("#stream-creation"));
const throttled_redraw_left_panel = _.throttle(redraw_left_panel, 50); const throttled_redraw_left_panel = _.throttle(redraw_left_panel, 50);
$("#stream_filter input[type='text']").on("input", () => { $("#stream_filter input[type='text']").on("input", () => {
// Debounce filtering in case a user is typing quickly // Debounce filtering in case a user is typing quickly

View File

@@ -7,6 +7,7 @@ import render_stream_can_subscribe_group_label from "../templates/stream_setting
import render_stream_privacy_icon from "../templates/stream_settings/stream_privacy_icon.hbs"; import render_stream_privacy_icon from "../templates/stream_settings/stream_privacy_icon.hbs";
import render_stream_settings_tip from "../templates/stream_settings/stream_settings_tip.hbs"; import render_stream_settings_tip from "../templates/stream_settings/stream_settings_tip.hbs";
import * as channel_folders from "./channel_folders.ts";
import * as hash_parser from "./hash_parser.ts"; import * as hash_parser from "./hash_parser.ts";
import {$t} from "./i18n.ts"; import {$t} from "./i18n.ts";
import * as overlays from "./overlays.ts"; import * as overlays from "./overlays.ts";
@@ -640,3 +641,33 @@ export function maybe_reset_channel_folder_dropdown(archived_folder_id: number):
update_setting_element(sub, "folder_id"); update_setting_element(sub, "folder_id");
} }
} }
export function set_folder_dropdown_visibility($container: JQuery): void {
if (current_user.is_admin) {
$container.find(".channel-folder-container").show();
$container.find(".no-folders-configured-message").hide();
return;
}
const realm_has_channel_folders = channel_folders.get_active_folder_ids().size > 0;
if (realm_has_channel_folders) {
$container.find(".channel-folder-container").show();
$container.find(".no-folders-configured-message").hide();
} else {
$container.find(".channel-folder-container").hide();
$container.find(".no-folders-configured-message").show();
}
}
export function update_folder_dropdown_visibility(): void {
if (!overlays.streams_open()) {
return;
}
set_folder_dropdown_visibility($("#stream-creation"));
const active_stream_id = stream_settings_components.get_active_data().id;
if (active_stream_id) {
set_folder_dropdown_visibility($("#stream_settings"));
}
}

View File

@@ -56,7 +56,6 @@
component so that we can show dropdown button and button to create component so that we can show dropdown button and button to create
a new folder on same line without having to add much CSS with a new folder on same line without having to add much CSS with
hardcoded margin and padding values. --}} hardcoded margin and padding values. --}}
{{#if (or is_admin realm_has_channel_folders)}}
<label class="settings-field-label" for="{{channel_folder_widget_name}}_widget"> <label class="settings-field-label" for="{{channel_folder_widget_name}}_widget">
{{t "Channel folder"}} {{t "Channel folder"}}
{{> ../help_link_widget link="/help/channel-folders" }} {{> ../help_link_widget link="/help/channel-folders" }}
@@ -75,13 +74,12 @@
}} }}
{{/if}} {{/if}}
</div> </div>
{{else}}
<span class="settings-field-label">
{{t "There are no channel folders configured in this organization."}}
{{> ../help_link_widget link="/help/channel-folders" }}
</span>
{{/if}}
</div> </div>
<span class="settings-field-label no-folders-configured-message">
{{t "There are no channel folders configured in this organization."}}
{{> ../help_link_widget link="/help/channel-folders" }}
</span>
</div> </div>
<div class="advanced-configurations-container {{#if is_stream_edit}}settings-subsection-parent{{/if}}"> <div class="advanced-configurations-container {{#if is_stream_edit}}settings-subsection-parent{{/if}}">

View File

@@ -91,7 +91,6 @@
group_setting_labels=../group_setting_labels group_setting_labels=../group_setting_labels
channel_folder_widget_name="folder_id" channel_folder_widget_name="folder_id"
is_admin=../is_admin is_admin=../is_admin
realm_has_channel_folders=../realm_has_channel_folders
}} }}
{{/with}} {{/with}}
<div class="stream_details_box"> <div class="stream_details_box">

View File

@@ -555,8 +555,12 @@ run_test("channel_folders", ({override}) => {
let event = event_fixtures.channel_folder__add; let event = event_fixtures.channel_folder__add;
{ {
const stub = make_stub();
override(stream_ui_updates, "update_folder_dropdown_visibility", stub.f);
dispatch(event); dispatch(event);
assert.equal(stub.num_calls, 1);
const folders = channel_folders.get_channel_folders(); const folders = channel_folders.get_channel_folders();
assert.equal(folders.length, 1); assert.equal(folders.length, 1);
assert.equal(folders[0].id, event.channel_folder.id); assert.equal(folders[0].id, event.channel_folder.id);
@@ -569,10 +573,17 @@ run_test("channel_folders", ({override}) => {
override(stream_settings_ui, "update_channel_folder_name", stub.f); override(stream_settings_ui, "update_channel_folder_name", stub.f);
override(stream_list, "update_streams_sidebar", stub.f); override(stream_list, "update_streams_sidebar", stub.f);
override(stream_settings_ui, "reset_dropdown_set_to_archived_folder", stub.f); override(stream_settings_ui, "reset_dropdown_set_to_archived_folder", stub.f);
const update_dropdown_visibility_stub = make_stub();
override(
stream_ui_updates,
"update_folder_dropdown_visibility",
update_dropdown_visibility_stub.f,
);
dispatch(event); dispatch(event);
assert.equal(stub.num_calls, 3); assert.equal(stub.num_calls, 3);
assert.equal(update_dropdown_visibility_stub.num_calls, 1);
const folders = channel_folders.get_channel_folders(true); const folders = channel_folders.get_channel_folders(true);
const args = stub.get_args("folder_id"); const args = stub.get_args("folder_id");
assert_same(args.folder_id, event.channel_folder_id); assert_same(args.folder_id, event.channel_folder_id);