mirror of
https://github.com/zulip/zulip.git
synced 2025-10-23 04:52:12 +00:00
stream_settings: Display archived channels.
By default, archived channels will be hidden.
This commit is contained in:
@@ -256,18 +256,13 @@ export function validate_channels_settings_hash(hash: string): string {
|
||||
const stream_id = Number.parseInt(section, 10);
|
||||
const sub = sub_store.get(stream_id);
|
||||
// There are a few situations where we can't display stream settings:
|
||||
// 1. This is a stream that's been archived. (sub.is_archived=true)
|
||||
// 2. The stream ID is invalid. (sub=undefined)
|
||||
// 3. The current user is a guest, and was unsubscribed from the stream
|
||||
// 1. The stream ID is invalid. (sub=undefined)
|
||||
// 2. The current user is a guest, and was unsubscribed from the stream
|
||||
// stream in the current session. (In future sessions, the stream will
|
||||
// not be in sub_store).
|
||||
//
|
||||
// In all these cases we redirect the user to 'subscribed' tab.
|
||||
if (
|
||||
sub === undefined ||
|
||||
sub.is_archived ||
|
||||
(page_params.is_guest && !stream_data.is_subscribed(stream_id))
|
||||
) {
|
||||
// In both cases we redirect the user to 'subscribed' tab.
|
||||
if (sub === undefined || (page_params.is_guest && !stream_data.is_subscribed(stream_id))) {
|
||||
return channels_settings_section_url();
|
||||
}
|
||||
|
||||
|
@@ -355,6 +355,10 @@ export function subscribed_stream_ids(): number[] {
|
||||
return subscribed_subs().map((sub) => sub.stream_id);
|
||||
}
|
||||
|
||||
export function get_archived_subs(): StreamSubscription[] {
|
||||
return [...stream_info.values()].filter((sub) => sub.is_archived);
|
||||
}
|
||||
|
||||
export function muted_stream_ids(): number[] {
|
||||
return subscribed_subs()
|
||||
.filter((sub) => sub.is_muted)
|
||||
|
@@ -28,6 +28,12 @@ export type SettingsSubscription = StreamSubscription & {
|
||||
subscriber_count: number;
|
||||
};
|
||||
|
||||
export const FILTERS = {
|
||||
ALL_CHANNELS: "all_channels",
|
||||
NON_ARCHIVED_CHANNELS: "non_archived_channels",
|
||||
ARCHIVED_CHANNELS: "archived_channels",
|
||||
};
|
||||
|
||||
export function get_sub_for_settings(sub: StreamSubscription): SettingsSubscription {
|
||||
return {
|
||||
...sub,
|
||||
@@ -66,7 +72,7 @@ function get_subs_for_settings(subs: StreamSubscription[]): SettingsSubscription
|
||||
// delegating, so that we can more efficiently compute subscriber counts
|
||||
// (in bulk). If that plan appears to have been aborted, feel free to
|
||||
// inline this.
|
||||
return subs.filter((sub) => !sub.is_archived).map((sub) => get_sub_for_settings(sub));
|
||||
return subs.map((sub) => get_sub_for_settings(sub));
|
||||
}
|
||||
|
||||
export function get_updated_unsorted_subs(): SettingsSubscription[] {
|
||||
|
@@ -1,6 +1,7 @@
|
||||
import $ from "jquery";
|
||||
import _ from "lodash";
|
||||
import assert from "minimalistic-assert";
|
||||
import type * as tippy from "tippy.js";
|
||||
|
||||
import render_stream_creation_confirmation_banner from "../templates/modal_banner/stream_creation_confirmation_banner.hbs";
|
||||
import render_stream_info_banner from "../templates/modal_banner/stream_info_banner.hbs";
|
||||
@@ -15,6 +16,7 @@ import type {Toggle} from "./components.ts";
|
||||
import * as compose_banner from "./compose_banner.ts";
|
||||
import * as compose_recipient from "./compose_recipient.ts";
|
||||
import * as compose_state from "./compose_state.ts";
|
||||
import * as dropdown_widget from "./dropdown_widget.ts";
|
||||
import * as hash_parser from "./hash_parser.ts";
|
||||
import * as hash_util from "./hash_util.ts";
|
||||
import {$t} from "./i18n.ts";
|
||||
@@ -46,6 +48,10 @@ import * as stream_ui_updates from "./stream_ui_updates.ts";
|
||||
import * as sub_store from "./sub_store.ts";
|
||||
import type {StreamSubscription} from "./sub_store.ts";
|
||||
import * as util from "./util.ts";
|
||||
import * as views_util from "./views_util.ts";
|
||||
|
||||
let archived_status_dropdown_filter: string;
|
||||
let filters_dropdown_widget: dropdown_widget.DropdownWidget;
|
||||
|
||||
export function is_sub_already_present(sub: StreamSubscription): boolean {
|
||||
return stream_ui_updates.row_for_stream_id(sub.stream_id).length > 0;
|
||||
@@ -384,6 +390,20 @@ export function update_settings_for_unsubscribed(slim_sub: StreamSubscription):
|
||||
}
|
||||
|
||||
function triage_stream(left_panel_params: LeftPanelParams, sub: StreamSubscription): string {
|
||||
const current_channel_visibility_filter = archived_status_dropdown_filter;
|
||||
const channel_visibility_filters = stream_settings_data.FILTERS;
|
||||
if (
|
||||
current_channel_visibility_filter === channel_visibility_filters.NON_ARCHIVED_CHANNELS &&
|
||||
sub.is_archived
|
||||
) {
|
||||
return "rejected";
|
||||
}
|
||||
if (
|
||||
current_channel_visibility_filter === channel_visibility_filters.ARCHIVED_CHANNELS &&
|
||||
!sub.is_archived
|
||||
) {
|
||||
return "rejected";
|
||||
}
|
||||
if (left_panel_params.show_subscribed && !sub.subscribed) {
|
||||
// reject non-subscribed streams
|
||||
return "rejected";
|
||||
@@ -485,12 +505,15 @@ export function update_empty_left_panel_message(): void {
|
||||
has_streams = stream_data.get_unsorted_subs().length;
|
||||
}
|
||||
|
||||
const has_hidden_streams =
|
||||
const all_channels_hidden =
|
||||
$("#channels_overlay_container .stream-row:not(.notdisplayed)").length === 0;
|
||||
const has_search_query =
|
||||
$<HTMLInputElement>("#stream_filter input[type='text']").val()!.trim() !== "";
|
||||
// Show "no channels match" text if all channels are hidden and there's a search query.
|
||||
if (has_hidden_streams && has_search_query) {
|
||||
const has_filter =
|
||||
archived_status_dropdown_filter !== stream_settings_data.FILTERS.ALL_CHANNELS;
|
||||
|
||||
// Both search queries and filters can lead to all channels being hidden.
|
||||
if (all_channels_hidden && (has_search_query || (has_filter && has_streams))) {
|
||||
$(".no-streams-to-show").children().hide();
|
||||
$(".no_stream_match_filter_empty_text").show();
|
||||
$(".no-streams-to-show").show();
|
||||
@@ -639,6 +662,66 @@ export function switch_stream_sort(tab_name: string): void {
|
||||
redraw_left_panel();
|
||||
}
|
||||
|
||||
function filters_dropdown_options(current_value: string | number | undefined): {
|
||||
unique_id: string;
|
||||
name: string;
|
||||
bold_current_selection: boolean;
|
||||
}[] {
|
||||
return [
|
||||
{
|
||||
unique_id: stream_settings_data.FILTERS.ARCHIVED_CHANNELS,
|
||||
name: $t({defaultMessage: "Archived channels"}),
|
||||
bold_current_selection:
|
||||
current_value === stream_settings_data.FILTERS.ARCHIVED_CHANNELS,
|
||||
},
|
||||
{
|
||||
unique_id: stream_settings_data.FILTERS.NON_ARCHIVED_CHANNELS,
|
||||
name: $t({defaultMessage: "Non-archived channels"}),
|
||||
bold_current_selection:
|
||||
current_value === stream_settings_data.FILTERS.NON_ARCHIVED_CHANNELS,
|
||||
},
|
||||
{
|
||||
unique_id: stream_settings_data.FILTERS.ALL_CHANNELS,
|
||||
name: $t({defaultMessage: "Archived and non-archived"}),
|
||||
bold_current_selection: current_value === stream_settings_data.FILTERS.ALL_CHANNELS,
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
export function set_filters_for_tests(filter_widget: dropdown_widget.DropdownWidget): void {
|
||||
filters_dropdown_widget = filter_widget;
|
||||
}
|
||||
|
||||
function filter_click_handler(
|
||||
event: JQuery.TriggeredEvent,
|
||||
dropdown: tippy.Instance,
|
||||
widget: dropdown_widget.DropdownWidget,
|
||||
): void {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
|
||||
const filter_id = $(event.currentTarget).attr("data-unique-id");
|
||||
assert(filter_id !== undefined);
|
||||
// We don't support multiple filters, so we clear existing and add the new filter.
|
||||
archived_status_dropdown_filter = filter_id;
|
||||
redraw_left_panel();
|
||||
dropdown.hide();
|
||||
widget.render();
|
||||
}
|
||||
|
||||
function set_up_dropdown_widget(): void {
|
||||
archived_status_dropdown_filter = stream_settings_data.FILTERS.NON_ARCHIVED_CHANNELS;
|
||||
filters_dropdown_widget = new dropdown_widget.DropdownWidget({
|
||||
...views_util.COMMON_DROPDOWN_WIDGET_PARAMS,
|
||||
get_options: filters_dropdown_options,
|
||||
widget_name: "stream_settings_filter",
|
||||
item_click_callback: filter_click_handler,
|
||||
$events_container: $("#stream_filter"),
|
||||
default_id: archived_status_dropdown_filter,
|
||||
});
|
||||
filters_dropdown_widget.setup();
|
||||
}
|
||||
|
||||
function setup_page(callback: () => void): void {
|
||||
// We should strongly consider only setting up the page once,
|
||||
// but I am writing these comments write before a big release,
|
||||
@@ -723,6 +806,7 @@ function setup_page(callback: () => void): void {
|
||||
const new_stream_announcements_stream_sub = stream_data.get_sub_by_name(
|
||||
new_stream_announcements_stream,
|
||||
);
|
||||
const realm_has_archived_channels = stream_data.get_archived_subs().length > 0;
|
||||
|
||||
const template_data = {
|
||||
new_stream_announcements_stream_sub,
|
||||
@@ -747,6 +831,7 @@ function setup_page(callback: () => void): void {
|
||||
disable_message_retention_setting:
|
||||
!realm.zulip_plan_is_not_limited || !current_user.is_owner,
|
||||
group_setting_labels: settings_config.all_group_setting_labels.stream,
|
||||
realm_has_archived_channels,
|
||||
};
|
||||
|
||||
const rendered = render_stream_settings_overlay(template_data);
|
||||
@@ -756,6 +841,7 @@ function setup_page(callback: () => void): void {
|
||||
initialize_components();
|
||||
redraw_left_panel();
|
||||
stream_create.set_up_handlers();
|
||||
set_up_dropdown_widget();
|
||||
|
||||
const throttled_redraw_left_panel = _.throttle(redraw_left_panel, 50);
|
||||
$("#stream_filter input[type='text']").on("input", () => {
|
||||
@@ -876,6 +962,23 @@ export function change_state(
|
||||
toggler.goto(left_side_tab);
|
||||
}
|
||||
switch_to_stream_row(stream_id);
|
||||
|
||||
const sub = stream_data.get_sub_by_id(stream_id);
|
||||
if (sub) {
|
||||
const FILTERS = stream_settings_data.FILTERS;
|
||||
const should_update_filter =
|
||||
(archived_status_dropdown_filter === FILTERS.NON_ARCHIVED_CHANNELS &&
|
||||
sub.is_archived) ||
|
||||
(archived_status_dropdown_filter === FILTERS.ARCHIVED_CHANNELS && !sub.is_archived);
|
||||
if (should_update_filter) {
|
||||
if (sub.is_archived) {
|
||||
archived_status_dropdown_filter = FILTERS.ARCHIVED_CHANNELS;
|
||||
} else {
|
||||
archived_status_dropdown_filter = FILTERS.NON_ARCHIVED_CHANNELS;
|
||||
}
|
||||
filters_dropdown_widget.render(archived_status_dropdown_filter);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
@@ -642,11 +642,21 @@ h4.user_group_setting_subsection_title {
|
||||
padding: 8px 10px;
|
||||
display: grid;
|
||||
grid-template:
|
||||
"search-input clear-search more-options-button" auto / minmax(0, 1fr)
|
||||
"search-input clear-search dropdown-widget" auto / minmax(0, 1fr)
|
||||
30px;
|
||||
border-bottom: 1px solid var(--color-border-modal-bar);
|
||||
}
|
||||
|
||||
#stream_settings_filter_widget {
|
||||
margin-left: 10px;
|
||||
gap: 3px;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.stream_settings_filter_container.hide_filter {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#user_group_visibility_settings_widget {
|
||||
grid-area: more-options-button;
|
||||
margin-left: 10px;
|
||||
|
@@ -1,5 +1,4 @@
|
||||
{{#if stream_settings_link}}
|
||||
{{#unless stream.is_archived}}
|
||||
<a class="message-header-stream-settings-button tippy-zulip-tooltip" data-tooltip-template-id="stream-details-tooltip-template" data-tippy-placement="bottom" href="{{stream_settings_link}}">
|
||||
{{> navbar_icon_and_title . }}
|
||||
</a>
|
||||
@@ -13,11 +12,6 @@
|
||||
{{/unless}}
|
||||
</div>
|
||||
</template>
|
||||
{{else}}
|
||||
<span class="navbar_title">
|
||||
{{> navbar_icon_and_title . }}
|
||||
</span>
|
||||
{{/unless}}
|
||||
<span class="narrow_description rendered_markdown single-line-rendered-markdown">
|
||||
{{#if rendered_narrow_description}}
|
||||
{{rendered_markdown rendered_narrow_description}}
|
||||
|
@@ -25,6 +25,9 @@
|
||||
<button type="button" class="clear_search_button" id="clear_search_stream_name">
|
||||
<i class="zulip-icon zulip-icon-close" aria-hidden="true"></i>
|
||||
</button>
|
||||
<div class="stream_settings_filter_container {{#unless realm_has_archived_channels}}hide_filter{{/unless}}">
|
||||
{{> ../dropdown_widget widget_name="stream_settings_filter"}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="no-streams-to-show">
|
||||
<div class="subscribed_streams_tab_empty_text">
|
||||
|
@@ -716,6 +716,7 @@ test("delete_sub", () => {
|
||||
|
||||
stream_data.add_sub(canada);
|
||||
const num_subscribed_subs = stream_data.num_subscribed_subs();
|
||||
const archived_subs = stream_data.get_archived_subs();
|
||||
|
||||
assert.ok(stream_data.is_subscribed(canada.stream_id));
|
||||
assert.equal(stream_data.get_sub("Canada").stream_id, canada.stream_id);
|
||||
@@ -728,6 +729,7 @@ test("delete_sub", () => {
|
||||
assert.ok(stream_data.get_sub("Canada"));
|
||||
assert.ok(sub_store.get(canada.stream_id));
|
||||
assert.equal(stream_data.num_subscribed_subs(), num_subscribed_subs);
|
||||
assert.equal(stream_data.get_archived_subs().length, archived_subs.length + 1);
|
||||
|
||||
blueslip.expect("warn", "Failed to archive stream 99999");
|
||||
stream_data.delete_sub(99999);
|
||||
|
@@ -209,6 +209,11 @@ run_test("redraw_left_panel", ({override, mock_template}) => {
|
||||
populated_subs = data.subscriptions;
|
||||
});
|
||||
|
||||
const filters_dropdown_widget = {
|
||||
render: function render() {},
|
||||
};
|
||||
stream_settings_ui.set_filters_for_tests(filters_dropdown_widget);
|
||||
|
||||
stream_settings_ui.render_left_panel_superset();
|
||||
|
||||
const sub_stubs = [];
|
||||
@@ -223,6 +228,11 @@ run_test("redraw_left_panel", ({override, mock_template}) => {
|
||||
|
||||
$.create("#channels_overlay_container .stream-row", {children: sub_stubs});
|
||||
|
||||
const $no_streams_message = $(".no-streams-to-show");
|
||||
const $child_element = $(".subscribed_streams_tab_empty_text");
|
||||
$no_streams_message.children = () => $child_element;
|
||||
$child_element.hide = () => [];
|
||||
|
||||
let ui_called = false;
|
||||
scroll_util.reset_scrollbar = ($elem) => {
|
||||
ui_called = true;
|
||||
@@ -360,6 +370,7 @@ run_test("redraw_left_panel", ({override, mock_template}) => {
|
||||
test_filter({input: "d", show_subscribed: true}, [poland]);
|
||||
assert.ok($(".stream-row-denmark").hasClass("active"));
|
||||
|
||||
$(".stream-row.active").attr("data-stream-id", 101);
|
||||
stream_settings_ui.switch_stream_tab("subscribed");
|
||||
assert.ok(!$(".stream-row-denmark").hasClass("active"));
|
||||
assert.ok(!$(".right .settings").visible());
|
||||
|
Reference in New Issue
Block a user