diff --git a/web/src/stream_popover.ts b/web/src/stream_popover.ts index 11873a1991..cc3e46628d 100644 --- a/web/src/stream_popover.ts +++ b/web/src/stream_popover.ts @@ -5,6 +5,7 @@ import {z} from "zod"; import render_inline_decorated_stream_name from "../templates/inline_decorated_stream_name.hbs"; import render_inline_stream_or_topic_reference from "../templates/inline_stream_or_topic_reference.hbs"; +import render_topic_already_exists_warning_banner from "../templates/modal_banner/topic_already_exists_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"; @@ -12,6 +13,7 @@ import * as blueslip from "./blueslip.ts"; import type {Typeahead} from "./bootstrap_typeahead.ts"; import * as browser_history from "./browser_history.ts"; import * as clipboard_handler from "./clipboard_handler.ts"; +import * as compose_banner from "./compose_banner.ts"; import * as composebox_typeahead from "./composebox_typeahead.ts"; import * as dialog_widget from "./dialog_widget.ts"; import * as dropdown_widget from "./dropdown_widget.ts"; @@ -32,6 +34,7 @@ import * as stream_data from "./stream_data.ts"; import * as stream_settings_api from "./stream_settings_api.ts"; import * as stream_settings_components from "./stream_settings_components.ts"; import * as stream_settings_ui from "./stream_settings_ui.ts"; +import * as stream_topic_history from "./stream_topic_history.ts"; import * as sub_store from "./sub_store.ts"; import * as ui_report from "./ui_report.ts"; import * as ui_util from "./ui_util.ts"; @@ -606,6 +609,57 @@ export async function build_move_topic_to_stream_popover( ); } + function show_topic_already_exists_warning(): boolean { + // Don't show warning if the submit button is disabled. + if ($("#move_topic_modal .dialog_submit_button").expectOne().prop("disabled")) { + return false; + } + // Don't show warning if we are only moving one message. + if ($("#move_topic_modal select.message_edit_topic_propagate").val() === "change_one") { + return false; + } + const {new_topic_name} = get_params_from_form(); + assert(new_topic_name !== undefined); + // Don't show warning for empty topic as the user is probably + // about to type a new topic name. Note that if topics are + // mandatory, then the submit button is disabled, which returns + // early above. + if (new_topic_name === "" || new_topic_name === "(no topic)") { + return false; + } + let stream_id: number; + if (stream_widget_value === undefined) { + // Set stream_id to current_stream_id since the user is not + // allowed to edit the stream in topic-edit only UI. + stream_id = current_stream_id; + } else { + stream_id = stream_widget_value; + } + const stream_topics = stream_topic_history + .get_recent_topic_names(stream_id) + .map((topic) => topic.toLowerCase()); + if (stream_topics.includes(new_topic_name.trim().toLowerCase())) { + return true; + } + return false; + } + + function maybe_show_topic_already_exists_warning(): void { + const $move_topic_warning_container = $("#move_topic_modal .move_topic_warning_container"); + if (show_topic_already_exists_warning()) { + $move_topic_warning_container.html( + render_topic_already_exists_warning_banner({ + banner_type: compose_banner.WARNING, + hide_close_button: true, + classname: "topic_already_exists_warning", + }), + ); + $move_topic_warning_container.show(); + } else { + $move_topic_warning_container.hide(); + } + } + function render_selected_stream(): void { assert(stream_widget_value !== undefined); const stream = stream_data.get_sub_by_id(stream_widget_value); @@ -626,6 +680,7 @@ export async function build_move_topic_to_stream_popover( update_submit_button_disabled_state(stream_widget_value); set_stream_topic_typeahead(); render_selected_stream(); + maybe_show_topic_already_exists_warning(); dropdown.hide(); event.preventDefault(); @@ -705,6 +760,7 @@ export async function build_move_topic_to_stream_popover( function move_topic_post_render(): void { $("#move_topic_modal .dialog_submit_button").prop("disabled", true); + $("#move_topic_modal .move_topic_warning_container").hide(); const $topic_input = $("#move_topic_form input.move_messages_edit_topic"); move_topic_to_stream_topic_typeahead = composebox_typeahead.initialize_topic_edit_typeahead( @@ -719,6 +775,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); + maybe_show_topic_already_exists_warning(); }); return; } @@ -749,10 +806,23 @@ export async function build_move_topic_to_stream_popover( render_selected_stream(); $("#move_topic_to_stream_widget").prop("disabled", disable_stream_input); - $("#move_topic_modal .move_messages_edit_topic").on("input", () => { + $topic_input.on("input", () => { update_submit_button_disabled_state(current_stream_id); + maybe_show_topic_already_exists_warning(); }); + // Update position of topic typeahead because showing/hiding the + // "topic already exists" warning changes the size of the modal. + const update_topic_typeahead_position = new ResizeObserver((_entries) => { + requestAnimationFrame(() => { + $topic_input.trigger(new $.Event("typeahead.refreshPosition")); + }); + }); + const move_topic_form = document.querySelector("#move_topic_form"); + if (move_topic_form) { + update_topic_typeahead_position.observe(move_topic_form); + } + if (!args.from_message_actions_popover) { update_move_messages_count_text("change_all"); } else { @@ -776,6 +846,7 @@ export async function build_move_topic_to_stream_popover( $("#message_move_select_options").on("change", function () { selected_option = String($(this).val()); last_propagate_mode_for_conversation.set(conversation_key, selected_option); + maybe_show_topic_already_exists_warning(); update_move_messages_count_text(selected_option, message?.id); }); } diff --git a/web/templates/modal_banner/topic_already_exists_warning_banner.hbs b/web/templates/modal_banner/topic_already_exists_warning_banner.hbs new file mode 100644 index 0000000000..5750021180 --- /dev/null +++ b/web/templates/modal_banner/topic_already_exists_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 fc953f04f3..fd8804827c 100644 --- a/web/templates/move_topic_to_stream.hbs +++ b/web/templates/move_topic_to_stream.hbs @@ -1,4 +1,5 @@
+
{{#unless only_topic_edit}}