diff --git a/web/src/stream_create.ts b/web/src/stream_create.ts index 2f58be4d7d..89a26bd3fb 100644 --- a/web/src/stream_create.ts +++ b/web/src/stream_create.ts @@ -3,9 +3,11 @@ import assert from "minimalistic-assert"; import {z} from "zod"; import render_subscription_invites_warning_modal from "../templates/confirm_dialog/confirm_subscription_invites_warning.hbs"; +import render_change_stream_info_modal from "../templates/stream_settings/change_stream_info_modal.hbs"; import * as channel from "./channel"; import * as confirm_dialog from "./confirm_dialog"; +import * as dialog_widget from "./dialog_widget"; import {$t, $t_html} from "./i18n"; import * as keydown_util from "./keydown_util"; import * as loading from "./loading"; @@ -16,6 +18,7 @@ import {current_user, realm} from "./state_data"; import * as stream_create_subscribers from "./stream_create_subscribers"; import * as stream_data from "./stream_data"; import * as stream_settings_components from "./stream_settings_components"; +import * as stream_settings_data from "./stream_settings_data"; import * as stream_ui_updates from "./stream_ui_updates"; import type {HTMLSelectOneElement} from "./types"; import * as ui_report from "./ui_report"; @@ -58,6 +61,12 @@ export function should_show_first_stream_created_modal(): boolean { return onboarding_steps.ONE_TIME_NOTICES_TO_DISPLAY.has("first_stream_created_banner"); } +export function maybe_update_error_message(): void { + if ($("#stream_name_error").is(":visible") && $("#archived_stream_rename").is(":visible")) { + $("#create_stream_name").trigger("input"); + } +} + class StreamSubscriptionError { report_no_subs_to_stream(): void { $("#stream_subscription_error").text( @@ -83,15 +92,16 @@ class StreamSubscriptionError { const stream_subscription_error = new StreamSubscriptionError(); class StreamNameError { - report_already_exists(): void { - $("#stream_name_error").text( - $t({defaultMessage: "A channel with this name already exists."}), - ); + report_already_exists(error?: string): void { + const error_message = + error ?? $t({defaultMessage: "A channel with this name already exists."}); + $("#stream_name_error").text(error_message); $("#stream_name_error").show(); } clear_errors(): void { $("#stream_name_error").hide(); + $("#archived_stream_rename").hide(); } report_empty_stream(): void { @@ -103,6 +113,12 @@ class StreamNameError { $("#create_stream_name").trigger("focus").trigger("select"); } + rename_archived_stream(stream_id: number): void { + $("#archived_stream_rename").text($t({defaultMessage: "Rename archived channel"})); + $("#archived_stream_rename").attr("data-stream-id", stream_id); + $("#archived_stream_rename").show(); + } + pre_validate(stream_name: string): void { // Don't worry about empty strings...we just want to call this // to warn users early before they start doing too much work @@ -111,8 +127,16 @@ class StreamNameError { // out it already exists, and I was just too lazy to look at // the public streams that I'm not subscribed to yet. Once I // realize the stream already exists, I may want to cancel.) - if (stream_name && stream_data.get_sub(stream_name)) { - this.report_already_exists(); + const stream = stream_data.get_sub(stream_name); + if (stream_name && stream) { + let error; + if (stream.is_archived) { + error = $t({defaultMessage: "An archived channel with this name already exists."}); + if (stream_settings_data.get_sub_for_settings(stream).can_change_name_description) { + this.rename_archived_stream(stream.stream_id); + } + } + this.report_already_exists(error); return; } @@ -126,8 +150,13 @@ class StreamNameError { return false; } - if (stream_data.get_sub(stream_name)) { - this.report_already_exists(); + const stream = stream_data.get_sub(stream_name); + if (stream) { + let error; + if (stream.is_archived) { + error = $t({defaultMessage: "An archived channel with this name already exists."}); + } + this.report_already_exists(error); this.select(); return false; } @@ -380,13 +409,19 @@ function create_stream(): void { // "Error creating channel"? stream_name_error.report_already_exists(); stream_name_error.select(); - } + const message = $t_html({ + defaultMessage: + "Error creating channel: A channel with this name already exists.", + }); - ui_report.error( - $t_html({defaultMessage: "Error creating channel"}), - xhr, - $(".stream_create_info"), - ); + ui_report.error(message, undefined, $(".stream_create_info")); + } else { + ui_report.error( + $t_html({defaultMessage: "Error creating channel"}), + xhr, + $(".stream_create_info"), + ); + } loading.destroy_indicator($("#stream_creating_indicator")); }, }); @@ -548,3 +583,56 @@ export function set_up_handlers(): void { assert(stream_settings_components.new_stream_can_remove_subscribers_group_widget !== null); stream_settings_components.new_stream_can_remove_subscribers_group_widget.setup(); } + +export function initialize(): void { + $("#channels_overlay_container").on("click", "#archived_stream_rename", (e) => { + e.preventDefault(); + e.stopPropagation(); + const stream_id = Number.parseInt($("#archived_stream_rename").attr("data-stream-id")!, 10); + const stream = stream_data.get_sub_by_id(stream_id); + + assert(stream !== undefined); + + const template_data = { + stream_name: stream.name, + stream_description: stream.description, + max_stream_name_length: realm.max_stream_name_length, + max_stream_description_length: realm.max_stream_description_length, + }; + const change_stream_info_modal = render_change_stream_info_modal(template_data); + dialog_widget.launch({ + html_heading: $t_html( + {defaultMessage: "Edit #{stream_name} (archived)"}, + {stream_name: stream.name}, + ), + html_body: change_stream_info_modal, + id: "change_stream_info_modal", + loading_spinner: true, + on_click: save_stream_info, + post_render() { + $("#change_stream_info_modal .dialog_submit_button") + .addClass("save-button") + .attr("data-stream-id", stream_id); + }, + update_submit_disabled_state_on_change: true, + }); + }); + + function save_stream_info(): void { + const stream_id = Number.parseInt($("#archived_stream_rename").attr("data-stream-id")!, 10); + const sub = stream_data.get_sub_by_id(stream_id); + const url = `/json/streams/${sub?.stream_id}`; + const data: {new_name?: string; description?: string} = {}; + const new_name = $("#change_stream_name").val()!.trim(); + const new_description = $("#change_stream_description").val()!.trim(); + + if (new_name !== sub?.name) { + data.new_name = new_name; + } + if (new_description !== sub?.description) { + data.description = new_description; + } + + dialog_widget.submit_api_request(channel.patch, url, data); + } +} diff --git a/web/src/stream_settings_ui.js b/web/src/stream_settings_ui.js index 39b8b3d739..1d4ff231ab 100644 --- a/web/src/stream_settings_ui.js +++ b/web/src/stream_settings_ui.js @@ -124,6 +124,9 @@ export function update_stream_name(sub, new_name) { // Update navbar if needed message_view_header.maybe_rerender_title_area_for_stream(sub); + + // Update the create stream error if needed + stream_create.maybe_update_error_message(); } export function update_stream_description(sub, description, rendered_description) { diff --git a/web/src/ui_init.js b/web/src/ui_init.js index 3a001a8b26..d14fafa093 100644 --- a/web/src/ui_init.js +++ b/web/src/ui_init.js @@ -117,6 +117,7 @@ import * as starred_messages from "./starred_messages"; import * as starred_messages_ui from "./starred_messages_ui"; import {current_user, realm, set_current_user, set_realm, state_data_schema} from "./state_data"; import * as stream_card_popover from "./stream_card_popover"; +import * as stream_create from "./stream_create"; import * as stream_data from "./stream_data"; import * as stream_edit from "./stream_edit"; import * as stream_edit_subscribers from "./stream_edit_subscribers"; @@ -533,6 +534,7 @@ export function initialize_everything(state_data) { on_send_message_success: compose.send_message_success, send_message: transmit.send_message, }); + stream_create.initialize(); stream_edit.initialize(); user_group_edit.initialize(); stream_edit_subscribers.initialize(); diff --git a/web/templates/stream_settings/stream_creation_form.hbs b/web/templates/stream_settings/stream_creation_form.hbs index dba3614862..7b2bc37e3e 100644 --- a/web/templates/stream_settings/stream_creation_form.hbs +++ b/web/templates/stream_settings/stream_creation_form.hbs @@ -13,6 +13,7 @@
+