diff --git a/web/src/stream_edit_subscribers.ts b/web/src/stream_edit_subscribers.ts index 62a774a6ec..cc547452c7 100644 --- a/web/src/stream_edit_subscribers.ts +++ b/web/src/stream_edit_subscribers.ts @@ -1,3 +1,4 @@ +import Handlebars from "handlebars/runtime.js"; import $ from "jquery"; import assert from "minimalistic-assert"; import {z} from "zod"; @@ -31,6 +32,7 @@ import * as subscriber_api from "./subscriber_api.ts"; import type {CombinedPillContainer} from "./typeahead_helper.ts"; import * as user_groups from "./user_groups.ts"; import * as user_sort from "./user_sort.ts"; +import * as util from "./util.ts"; const remove_user_id_api_response_schema = z.object({ removed: z.array(z.string()), @@ -68,37 +70,81 @@ function get_sub(stream_id: number): StreamSubscription | undefined { return sub; } -function show_stream_subscription_request_result({ - message, - add_class, - remove_class, - subscribed_users, - already_subscribed_users, - ignored_deactivated_users, -}: { - message?: string; - add_class: string; - remove_class: string; - subscribed_users?: User[]; - already_subscribed_users?: User[]; - ignored_deactivated_users?: User[]; -}): void { +function generate_subscribe_success_messages( + subscribed_users: User[], + already_subscribed_users: User[], +): { + subscribed_users_message: string; + already_subscribed_users_message: string; +} { + const subscribed_user_links = subscribed_users.map( + (user) => + `${Handlebars.Utils.escapeExpression(user.full_name)}`, + ); + const already_subscribed_user_links = already_subscribed_users.map( + (user) => + `${Handlebars.Utils.escapeExpression(user.full_name)}`, + ); + + const subscribed_users_message = util.format_array_as_list_with_conjunction( + subscribed_user_links, + "long", + ); + const already_subscribed_users_message = util.format_array_as_list_with_conjunction( + already_subscribed_user_links, + "long", + ); + return { + subscribed_users_message, + already_subscribed_users_message, + }; +} + +function show_stream_subscription_request_error_result(error_message: string): void { const $stream_subscription_req_result_elem = $( ".stream_subscription_request_result", ).expectOne(); const html = render_stream_subscription_request_result({ - message, + error_message, + }); + scroll_util.get_content_element($stream_subscription_req_result_elem).html(html); +} + +function show_stream_subscription_request_success_result({ + subscribed_users, + already_subscribed_users, + ignored_deactivated_users, +}: { + subscribed_users: User[]; + already_subscribed_users: User[]; + ignored_deactivated_users: User[]; +}): void { + const subscribed_users_count = subscribed_users.length; + const already_subscribed_users_count = already_subscribed_users.length; + const is_total_subscriber_more_than_five = + subscribed_users_count + already_subscribed_users_count > 5; + + const $stream_subscription_req_result_elem = $( + ".stream_subscription_request_result", + ).expectOne(); + + let subscribe_success_messages; + if (!is_total_subscriber_more_than_five) { + subscribe_success_messages = generate_subscribe_success_messages( + subscribed_users, + already_subscribed_users, + ); + } + const html = render_stream_subscription_request_result({ + subscribe_success_messages, subscribed_users, already_subscribed_users, + subscribed_users_count, + already_subscribed_users_count, + is_total_subscriber_more_than_five, ignored_deactivated_users, }); scroll_util.get_content_element($stream_subscription_req_result_elem).html(html); - if (add_class) { - $stream_subscription_req_result_elem.addClass(add_class); - } - if (remove_class) { - $stream_subscription_req_result_elem.removeClass(remove_class); - } } function update_notification_choice_checkbox(added_user_count: number): void { @@ -265,18 +311,20 @@ function subscribe_new_users({pill_user_ids}: {pill_user_ids: number[]}): void { people.get_by_user_id(user_id), ); } - if (user_id_set.size === 0) { - show_stream_subscription_request_result({ - message: $t({defaultMessage: "No user to subscribe."}), - add_class: "text-error", - remove_class: "text-success", + + const user_ids = [...user_id_set]; + if (user_ids.length === 0) { + // No need to make a network call in this case. + // This will show "All users were already subscribed." + pill_widget.clear(); + show_stream_subscription_request_success_result({ + subscribed_users: [], + already_subscribed_users: [], ignored_deactivated_users, }); return; } - const user_ids = [...user_id_set]; - function invite_success(raw_data: unknown): void { const data = add_user_ids_api_response_schema.parse(raw_data); pill_widget.clear(); @@ -287,9 +335,7 @@ function subscribe_new_users({pill_user_ids}: {pill_user_ids: number[]}): void { people.get_by_user_id(Number(user_id)), ); - show_stream_subscription_request_result({ - add_class: "text-success", - remove_class: "text-error", + show_stream_subscription_request_success_result({ subscribed_users, already_subscribed_users, ignored_deactivated_users, @@ -297,7 +343,7 @@ function subscribe_new_users({pill_user_ids}: {pill_user_ids: number[]}): void { } function invite_failure(xhr: JQuery.jqXHR): void { - let message = "Failed to subscribe user!"; + let error_message = "Failed to subscribe user!"; const parsed = z .object({ @@ -308,13 +354,9 @@ function subscribe_new_users({pill_user_ids}: {pill_user_ids: number[]}): void { .safeParse(xhr.responseJSON); if (parsed.success) { - message = parsed.data.msg; + error_message = parsed.data.msg; } - show_stream_subscription_request_result({ - message, - add_class: "text-error", - remove_class: "text-success", - }); + show_stream_subscription_request_error_result(error_message); } subscriber_api.add_user_ids_to_stream( @@ -359,11 +401,8 @@ function remove_subscriber({ function removal_failure(): void { buttons.hide_button_loading_indicator($remove_button); - show_stream_subscription_request_result({ - message: $t({defaultMessage: "Error removing user from this channel."}), - add_class: "text-error", - remove_class: "text-success", - }); + const error_message = $t({defaultMessage: "Error removing user from this channel."}); + show_stream_subscription_request_error_result(error_message); } function remove_user_from_private_stream(): void { diff --git a/web/styles/subscriptions.css b/web/styles/subscriptions.css index 2e601f3cb6..71545efcd4 100644 --- a/web/styles/subscriptions.css +++ b/web/styles/subscriptions.css @@ -155,6 +155,10 @@ h4.user_group_setting_subsection_title { .subscriber_list_settings_container { display: flex; flex-direction: column; + + .input-group { + margin-bottom: 10px; + } } .add-group-member-loading-spinner, @@ -242,13 +246,14 @@ h4.user_group_setting_subsection_title { .member_list_add { width: 100%; margin: 0 0 10px; +} - .user_group_subscription_request_result, - .stream_subscription_request_result { - & a { - color: inherit; - } +.user_group_subscription_request_result, +.stream_subscription_request_result { + & a { + color: inherit; } + margin-bottom: 10px; } .member-search, diff --git a/web/templates/stream_settings/stream_members.hbs b/web/templates/stream_settings/stream_members.hbs index eee5fcf403..550cc8cda2 100644 --- a/web/templates/stream_settings/stream_members.hbs +++ b/web/templates/stream_settings/stream_members.hbs @@ -5,8 +5,8 @@
- {{> add_subscribers_form .}}
+ {{> add_subscribers_form .}}
diff --git a/web/templates/stream_settings/stream_subscription_request_result.hbs b/web/templates/stream_settings/stream_subscription_request_result.hbs index db87a29dd1..a7c80dfc2f 100644 --- a/web/templates/stream_settings/stream_subscription_request_result.hbs +++ b/web/templates/stream_settings/stream_subscription_request_result.hbs @@ -1,26 +1,43 @@ -{{#if message}} -{{message}} -
-{{/if}} -{{#if subscribed_users}} - {{#if subscribed_users.[1]}} - {{t "Successfully subscribed users:" }} - {{else}} - {{t "Successfully subscribed user:" }} - {{/if}} - {{#each subscribed_users}} - {{full_name}}{{#unless @last}},{{else}}.{{/unless}} - {{/each}} -
-{{/if}} -{{#if already_subscribed_users}} - {{#each already_subscribed_users}} - {{#if @first}} - {{t "Already subscribed users:" }} - {{/if}} - {{full_name}}{{#unless @last}},{{else}}.{{/unless}} - {{/each}} -
+{{#if error_message}} + +{{else}} + {{/if}} {{#if ignored_deactivated_users}} {{#each ignored_deactivated_users}}