diff --git a/web/src/list_widget.ts b/web/src/list_widget.ts index a6a460984f..e9ad86c006 100644 --- a/web/src/list_widget.ts +++ b/web/src/list_widget.ts @@ -1,6 +1,9 @@ import $ from "jquery"; import assert from "minimalistic-assert"; +import render_empty_list_widget_for_list from "../templates/empty_list_widget_for_list.hbs"; +import render_empty_list_widget_for_table from "../templates/empty_list_widget_for_table.hbs"; + import * as blueslip from "./blueslip"; import * as scroll_util from "./scroll_util"; @@ -177,6 +180,44 @@ function is_scroll_position_for_render(scroll_container: HTMLElement): boolean { ); } +function get_column_count_for_table($table: JQuery): number { + let column_count = 0; + const $thead = $table.find("thead"); + if ($thead.length) { + column_count = $thead.find("tr").children().length; + } + return column_count; +} + +export function render_empty_list_message_if_needed($container: JQuery): void { + const empty_list_message = $container.data("empty"); + + if (!empty_list_message || $container.children().length) { + return; + } + + let empty_list_widget; + + if ($container.is("table, tbody")) { + let $table = $container; + if ($container.is("tbody")) { + $table = $container.closest("table"); + } + + const column_count = get_column_count_for_table($table); + empty_list_widget = render_empty_list_widget_for_table({ + empty_list_message, + column_count, + }); + } else { + empty_list_widget = render_empty_list_widget_for_list({ + empty_list_message, + }); + } + + $container.append(empty_list_widget); +} + // @params // $container: jQuery object to append to. // list: The list of items to progressively append. @@ -249,6 +290,7 @@ export function create( // Stop once the offset reaches the length of the original list. if (meta.offset >= meta.filtered_list.length) { + render_empty_list_message_if_needed($container); return; } diff --git a/web/src/user_profile.js b/web/src/user_profile.js index d24cd0317a..96d77e53af 100644 --- a/web/src/user_profile.js +++ b/web/src/user_profile.js @@ -201,11 +201,19 @@ function render_user_stream_list(streams, user) { modifier_html(item) { return format_user_stream_list_item_html(item, user); }, + callback_after_render() { + $container.parent().removeClass("empty-list"); + }, filter: { $element: $("#user-profile-streams-tab .stream-search"), predicate(item, value) { return item && item.name.toLocaleLowerCase().includes(value); }, + onupdate() { + if ($container.find("#empty-table-message").length) { + $container.parent().addClass("empty-list"); + } + }, }, $simplebar_container: $("#user-profile-modal .modal__body"), }); @@ -218,6 +226,9 @@ function render_user_group_list(groups, user) { ListWidget.create($container, groups, { name: `user-${user.user_id}-group-list`, get_item: ListWidget.default_get_item, + callback_after_render() { + $container.parent().removeClass("empty-list"); + }, modifier_html(item) { return format_user_group_list_item_html(item); }, diff --git a/web/styles/app_components.css b/web/styles/app_components.css index 62ca86b740..c4fd042cf1 100644 --- a/web/styles/app_components.css +++ b/web/styles/app_components.css @@ -1163,6 +1163,15 @@ div.overlay { } } +#empty-list-message, +#empty-table-message { + background-color: inherit; + color: var(--color-text-default); + font-size: 1.5em; + padding: 3em 1em; + text-align: center; +} + .filter_text_input { padding: 4px 6px; color: hsl(0deg 0% 33%); diff --git a/web/styles/popovers.css b/web/styles/popovers.css index da521f1b73..0753d867f5 100644 --- a/web/styles/popovers.css +++ b/web/styles/popovers.css @@ -673,6 +673,14 @@ ul { } } } + + .empty-list { + border: none; + + #empty-table-message { + padding: 3em 1em; + } + } } @media (width < $md_min) { diff --git a/web/styles/recent_view.css b/web/styles/recent_view.css index 4d98e4e11c..b20092c4ae 100644 --- a/web/styles/recent_view.css +++ b/web/styles/recent_view.css @@ -61,6 +61,11 @@ position: absolute; } + #empty-table-message { + background-color: var(--color-background); + padding: 3em 1em; + } + .fa-check-square-o, .fa-square-o { padding: 0 2px; diff --git a/web/templates/empty_list_widget_for_list.hbs b/web/templates/empty_list_widget_for_list.hbs new file mode 100644 index 0000000000..191d781be2 --- /dev/null +++ b/web/templates/empty_list_widget_for_list.hbs @@ -0,0 +1 @@ +
  • {{empty_list_message}}
  • diff --git a/web/templates/empty_list_widget_for_table.hbs b/web/templates/empty_list_widget_for_table.hbs new file mode 100644 index 0000000000..63767c8b18 --- /dev/null +++ b/web/templates/empty_list_widget_for_table.hbs @@ -0,0 +1,5 @@ + + + {{empty_list_message}} + + diff --git a/web/templates/user_profile_modal.hbs b/web/templates/user_profile_modal.hbs index 0d7da2c9c5..a38df60e32 100644 --- a/web/templates/user_profile_modal.hbs +++ b/web/templates/user_profile_modal.hbs @@ -109,13 +109,13 @@ -
    +
    -
    +
    diff --git a/web/tests/list_widget.test.js b/web/tests/list_widget.test.js index 392ba84950..a81a69eb81 100644 --- a/web/tests/list_widget.test.js +++ b/web/tests/list_widget.test.js @@ -46,6 +46,7 @@ const ListWidget = zrequire("list_widget"); function make_container() { const $container = {}; $container.empty = () => {}; + $container.data = () => {}; // Make our append function just set a field we can // check in our tests.