diff --git a/web/src/stream_popover.js b/web/src/stream_popover.js index 993357ffd8d64e..6650b421eb8007 100644 --- a/web/src/stream_popover.js +++ b/web/src/stream_popover.js @@ -3,12 +3,14 @@ import $ from "jquery"; import assert from "minimalistic-assert"; import render_inline_decorated_stream_name from "../templates/inline_decorated_stream_name.hbs"; +import render_message_moving_warning_banner from "../templates/modal_banner/message_moving_warning_banner.hbs"; import render_move_topic_to_stream from "../templates/move_topic_to_stream.hbs"; import render_left_sidebar_stream_actions_popover from "../templates/popovers/left_sidebar/left_sidebar_stream_actions_popover.hbs"; import * as blueslip from "./blueslip"; import * as browser_history from "./browser_history"; import * as compose_actions from "./compose_actions"; +import * as compose_banner from "./compose_banner"; import * as composebox_typeahead from "./composebox_typeahead"; import * as dialog_widget from "./dialog_widget"; import * as dropdown_widget from "./dropdown_widget"; @@ -27,6 +29,7 @@ import * as stream_data from "./stream_data"; import * as stream_settings_api from "./stream_settings_api"; import * as stream_settings_components from "./stream_settings_components"; import * as stream_settings_ui from "./stream_settings_ui"; +import * as stream_topic_history from "./stream_topic_history"; import * as sub_store from "./sub_store"; import * as ui_report from "./ui_report"; import * as ui_util from "./ui_util"; @@ -558,6 +561,7 @@ export async function build_move_topic_to_stream_popover( stream_widget_value = $(event.currentTarget).attr("data-unique-id"); update_submit_button_disabled_state(stream_widget_value); + update_warning_banner(); set_stream_topic_typeahead(); render_selected_stream(); @@ -566,9 +570,55 @@ export async function build_move_topic_to_stream_popover( event.stopPropagation(); } + function update_warning_banner() { + // The warning banner only shows when + // 1) submit button is NOT disabled, and + // 2) target topic is an existing topic, and + // 3) propagate_mode is NOT change_one + + // submit button + if ($("#move_topic_modal .dialog_submit_button")[0].disabled) { + $("#move_topic_modal .move_topic_form_warning_container").html(""); + return; + } + + // target topic + if (stream_widget_value !== undefined) { + const {new_topic_name} = get_params_from_form(); + if ( + !stream_topic_history.stream_has_topic( + Number.parseInt(stream_widget_value, 10), + new_topic_name, + ) + ) { + $("#move_topic_modal .move_topic_form_warning_container").html(""); + return; + } + } + + // propagate_mode + if ($("#move_topic_modal select.message_edit_topic_propagate").val() === "change_one") { + $("#move_topic_modal .move_topic_form_warning_container").html(""); + return; + } + + $("#move_topic_modal .move_topic_form_warning_container").html( + render_message_moving_warning_banner({ + banner_type: compose_banner.WARNING, + hide_close_button: true, + classname: "message_moving_warning_banner", + }), + ); + } + function move_topic_post_render() { $("#move_topic_modal .dialog_submit_button").prop("disabled", true); + $("#move_topic_modal select.message_edit_topic_propagate")[0]?.addEventListener( + "change", + () => update_warning_banner(), + ); + const $topic_input = $("#move_topic_form .move_messages_edit_topic"); move_topic_to_stream_topic_typeahead = composebox_typeahead.initialize_topic_edit_typeahead( $topic_input, @@ -582,6 +632,7 @@ export async function build_move_topic_to_stream_popover( const select_stream_id = current_stream_id; $topic_input.on("input", () => { update_submit_button_disabled_state(select_stream_id); + update_warning_banner(); }); return; } @@ -610,6 +661,7 @@ export async function build_move_topic_to_stream_popover( $("#move_topic_to_stream_widget").prop("disabled", disable_stream_input); $("#move_topic_modal .move_messages_edit_topic").on("input", () => { update_submit_button_disabled_state(stream_widget_value); + update_warning_banner(); }); } diff --git a/web/src/stream_topic_history.ts b/web/src/stream_topic_history.ts index dc3157b81bb256..80b1cbf9913dda 100644 --- a/web/src/stream_topic_history.ts +++ b/web/src/stream_topic_history.ts @@ -86,6 +86,17 @@ export function stream_has_topics(stream_id: number): boolean { return history.has_topics(); } +export function stream_has_topic(stream_id: number, topic_name: string): boolean { + if (!stream_dict.has(stream_id)) { + return false; + } + + const history = stream_dict.get(stream_id); + assert(history !== undefined); + + return history.has_topic(topic_name); +} + export type TopicHistoryEntry = { count: number; message_id: number; @@ -126,6 +137,10 @@ export class PerStreamHistory { return this.topics.size !== 0; } + has_topic(topic_name: string): boolean { + return this.topics.has(topic_name); + } + update_stream_with_message_id(message_id: number): void { if (message_id > this.max_message_id) { this.max_message_id = message_id; diff --git a/web/templates/modal_banner/message_moving_warning_banner.hbs b/web/templates/modal_banner/message_moving_warning_banner.hbs new file mode 100644 index 00000000000000..ee88ec414e715c --- /dev/null +++ b/web/templates/modal_banner/message_moving_warning_banner.hbs @@ -0,0 +1,7 @@ +{{#> modal_banner }} + +{{/modal_banner}} diff --git a/web/templates/move_topic_to_stream.hbs b/web/templates/move_topic_to_stream.hbs index 2441af76f922cf..eb9635df1974d4 100644 --- a/web/templates/move_topic_to_stream.hbs +++ b/web/templates/move_topic_to_stream.hbs @@ -1,7 +1,8 @@ {{#unless (or from_message_actions_popover only_topic_edit)}}

{{#tr}}Move all messages in {topic_name}{{/tr}} to:

{{/unless}} -
+ +
{{#if only_topic_edit }}

{{t "Rename topic to:" }}

{{else if from_message_actions_popover}} diff --git a/web/tests/stream_topic_history.test.js b/web/tests/stream_topic_history.test.js index 42b33b95a28333..888b978e92b98b 100644 --- a/web/tests/stream_topic_history.test.js +++ b/web/tests/stream_topic_history.test.js @@ -307,6 +307,25 @@ test("test_stream_has_topics", () => { assert.equal(stream_topic_history.stream_has_topics(stream_id), true); }); +test("test_stream_has_topic", () => { + const stream_id = 88; + const topic_name = "fake topic name"; + + assert.equal(stream_topic_history.stream_has_topic(stream_id, topic_name), false); + + stream_topic_history.find_or_create(stream_id); + + assert.equal(stream_topic_history.stream_has_topic(stream_id, topic_name), false); + + stream_topic_history.add_message({ + stream_id, + message_id: 888, + topic_name, + }); + + assert.equal(stream_topic_history.stream_has_topic(stream_id, topic_name), true); +}); + test("server_history_end_to_end", () => { stream_topic_history.reset();