mirror of https://github.com/zulip/zulip.git
narrow_banner: Move empty narrow messages to handlebar templates.
Removed existing empty narrow divs from app/home.html and created a new javascript module to dynamically load empty narrow messages using handlebar template. Fixes #18797
This commit is contained in:
parent
f5bb43aba2
commit
aa002f5c6d
|
@ -16,6 +16,15 @@ const stream_data = zrequire("stream_data");
|
|||
const {Filter} = zrequire("../js/filter");
|
||||
const narrow = zrequire("narrow");
|
||||
|
||||
function empty_narrow_html(title, html, search_data) {
|
||||
const opts = {
|
||||
title,
|
||||
html,
|
||||
search_data,
|
||||
};
|
||||
return require("../../static/templates/empty_feed_notice.hbs")(opts);
|
||||
}
|
||||
|
||||
function set_filter(operators) {
|
||||
operators = operators.map((op) => ({
|
||||
operator: op[0],
|
||||
|
@ -67,6 +76,95 @@ function hide_all_empty_narrow_messages() {
|
|||
}
|
||||
}
|
||||
|
||||
run_test("empty_narrow_html", ({mock_template}) => {
|
||||
mock_template("empty_feed_notice.hbs", true, (data, html) => html);
|
||||
|
||||
let actual_html = empty_narrow_html("This is a title", "<h1> This is the html </h1>");
|
||||
assert.equal(
|
||||
actual_html,
|
||||
`<div class="empty_feed_notice">
|
||||
<h4> This is a title </h4>
|
||||
<h1> This is the html </h1>
|
||||
</div>
|
||||
`,
|
||||
);
|
||||
|
||||
const search_data_with_all_search_types = {
|
||||
topic_query: "test",
|
||||
stream_query: "new",
|
||||
has_stop_word: true,
|
||||
query_words: [
|
||||
{query_word: "search", is_stop_word: false},
|
||||
{query_word: "a", is_stop_word: true},
|
||||
],
|
||||
};
|
||||
actual_html = empty_narrow_html(
|
||||
"This is a title",
|
||||
undefined,
|
||||
search_data_with_all_search_types,
|
||||
);
|
||||
assert.equal(
|
||||
actual_html,
|
||||
`<div class="empty_feed_notice">
|
||||
<h4> This is a title </h4>
|
||||
<div>
|
||||
Some common words were excluded from your search. <br/>You searched for:
|
||||
<span>stream: new</span>
|
||||
<span>topic: test</span>
|
||||
<span>search</span>
|
||||
<del>a</del>
|
||||
</div>
|
||||
</div>
|
||||
`,
|
||||
);
|
||||
|
||||
const search_data_with_stream_without_stop_words = {
|
||||
has_stop_word: false,
|
||||
stream_query: "hello world",
|
||||
query_words: [{query_word: "searchA", is_stop_word: false}],
|
||||
};
|
||||
actual_html = empty_narrow_html(
|
||||
"This is a title",
|
||||
undefined,
|
||||
search_data_with_stream_without_stop_words,
|
||||
);
|
||||
assert.equal(
|
||||
actual_html,
|
||||
`<div class="empty_feed_notice">
|
||||
<h4> This is a title </h4>
|
||||
<div>
|
||||
You searched for:
|
||||
<span>stream: hello world</span>
|
||||
<span>searchA</span>
|
||||
</div>
|
||||
</div>
|
||||
`,
|
||||
);
|
||||
|
||||
const search_data_with_topic_without_stop_words = {
|
||||
has_stop_word: false,
|
||||
topic_query: "hello",
|
||||
query_words: [{query_word: "searchB", is_stop_word: false}],
|
||||
};
|
||||
actual_html = empty_narrow_html(
|
||||
"This is a title",
|
||||
undefined,
|
||||
search_data_with_topic_without_stop_words,
|
||||
);
|
||||
assert.equal(
|
||||
actual_html,
|
||||
`<div class="empty_feed_notice">
|
||||
<h4> This is a title </h4>
|
||||
<div>
|
||||
You searched for:
|
||||
<span>topic: hello</span>
|
||||
<span>searchB</span>
|
||||
</div>
|
||||
</div>
|
||||
`,
|
||||
);
|
||||
});
|
||||
|
||||
run_test("uris", () => {
|
||||
people.add_active_user(ray);
|
||||
people.add_active_user(alice);
|
||||
|
@ -92,111 +190,171 @@ run_test("uris", () => {
|
|||
assert.equal(emails, "me@example.com");
|
||||
});
|
||||
|
||||
run_test("show_empty_narrow_message", () => {
|
||||
run_test("show_empty_narrow_message", ({mock_template}) => {
|
||||
page_params.stop_words = [];
|
||||
|
||||
mock_template("empty_feed_notice.hbs", true, (data, html) => html);
|
||||
|
||||
narrow_state.reset_current_filter();
|
||||
hide_all_empty_narrow_messages();
|
||||
narrow_banner.show_empty_narrow_message();
|
||||
assert.equal($(".empty_feed_notice").visible(), false);
|
||||
assert.ok($("#empty_narrow_message").visible());
|
||||
assert.equal(
|
||||
$(".empty_feed_notice_main").html(),
|
||||
empty_narrow_html(
|
||||
"translated: Nothing's been sent here yet!",
|
||||
'translated HTML: Why not <a href="#" class="empty_feed_compose_stream">start the conversation</a>?',
|
||||
),
|
||||
);
|
||||
|
||||
// for non-existent or private stream
|
||||
set_filter([["stream", "Foo"]]);
|
||||
hide_all_empty_narrow_messages();
|
||||
narrow_banner.show_empty_narrow_message();
|
||||
assert.ok($("#nonsubbed_private_nonexistent_stream_narrow_message").visible());
|
||||
assert.equal(
|
||||
$(".empty_feed_notice_main").html(),
|
||||
empty_narrow_html("translated: This stream does not exist or is private."),
|
||||
);
|
||||
|
||||
// for non sub public stream
|
||||
stream_data.add_sub({name: "ROME", stream_id: 99});
|
||||
set_filter([["stream", "Rome"]]);
|
||||
hide_all_empty_narrow_messages();
|
||||
narrow_banner.show_empty_narrow_message();
|
||||
assert.ok($("#nonsubbed_stream_narrow_message").visible());
|
||||
assert.equal(
|
||||
$(".empty_feed_notice_main").html(),
|
||||
empty_narrow_html(
|
||||
"translated: You aren't subscribed to this stream and nobody has talked about that yet!",
|
||||
'translated HTML: <button class="button white rounded stream_sub_unsub_button sea-green" type="button" name="subscription">Subscribe</button>',
|
||||
),
|
||||
);
|
||||
|
||||
set_filter([["is", "starred"]]);
|
||||
hide_all_empty_narrow_messages();
|
||||
narrow_banner.show_empty_narrow_message();
|
||||
assert.ok($("#empty_star_narrow_message").visible());
|
||||
assert.equal(
|
||||
$(".empty_feed_notice_main").html(),
|
||||
empty_narrow_html(
|
||||
"translated: You haven't starred anything yet!",
|
||||
'translated HTML: Learn more about starring messages <a href="/help/star-a-message">here</a>.',
|
||||
),
|
||||
);
|
||||
|
||||
set_filter([["is", "mentioned"]]);
|
||||
hide_all_empty_narrow_messages();
|
||||
narrow_banner.show_empty_narrow_message();
|
||||
assert.ok($("#empty_narrow_all_mentioned").visible());
|
||||
assert.equal(
|
||||
$(".empty_feed_notice_main").html(),
|
||||
empty_narrow_html(
|
||||
"translated: You haven't been mentioned yet!",
|
||||
'translated HTML: Learn more about mentions <a href="/help/mention-a-user-or-group">here</a>.',
|
||||
),
|
||||
);
|
||||
|
||||
set_filter([["is", "private"]]);
|
||||
hide_all_empty_narrow_messages();
|
||||
narrow_banner.show_empty_narrow_message();
|
||||
assert.ok($("#empty_narrow_all_private_message").visible());
|
||||
assert.equal(
|
||||
$(".empty_feed_notice_main").html(),
|
||||
empty_narrow_html(
|
||||
"translated: You have no private messages yet!",
|
||||
'translated HTML: Why not <a href="#" class="empty_feed_compose_private">start the conversation</a>?',
|
||||
),
|
||||
);
|
||||
|
||||
set_filter([["is", "unread"]]);
|
||||
hide_all_empty_narrow_messages();
|
||||
narrow_banner.show_empty_narrow_message();
|
||||
assert.ok($("#no_unread_narrow_message").visible());
|
||||
assert.equal(
|
||||
$(".empty_feed_notice_main").html(),
|
||||
empty_narrow_html("translated: You have no unread messages!"),
|
||||
);
|
||||
|
||||
set_filter([["is", "resolved"]]);
|
||||
hide_all_empty_narrow_messages();
|
||||
narrow_banner.show_empty_narrow_message();
|
||||
assert.ok($("#empty_narrow_resolved_topics").visible());
|
||||
assert.equal(
|
||||
$(".empty_feed_notice_main").html(),
|
||||
empty_narrow_html("translated: No topics are marked as resolved."),
|
||||
);
|
||||
|
||||
set_filter([["pm-with", ["Yo"]]]);
|
||||
hide_all_empty_narrow_messages();
|
||||
narrow_banner.show_empty_narrow_message();
|
||||
assert.ok($("#non_existing_user").visible());
|
||||
assert.equal(
|
||||
$(".empty_feed_notice_main").html(),
|
||||
empty_narrow_html("translated: This user does not exist!"),
|
||||
);
|
||||
|
||||
people.add_active_user(alice);
|
||||
set_filter([["pm-with", ["alice@example.com", "Yo"]]]);
|
||||
hide_all_empty_narrow_messages();
|
||||
narrow_banner.show_empty_narrow_message();
|
||||
assert.ok($("#non_existing_users").visible());
|
||||
assert.equal(
|
||||
$(".empty_feed_notice_main").html(),
|
||||
empty_narrow_html("translated: One or more of these users do not exist!"),
|
||||
);
|
||||
|
||||
set_filter([["pm-with", "alice@example.com"]]);
|
||||
hide_all_empty_narrow_messages();
|
||||
narrow_banner.show_empty_narrow_message();
|
||||
assert.ok($("#empty_narrow_private_message").visible());
|
||||
assert.equal(
|
||||
$(".empty_feed_notice_main").html(),
|
||||
empty_narrow_html(
|
||||
"translated: You have no private messages with this person yet!",
|
||||
'translated HTML: Why not <a href="#" class="empty_feed_compose_private">start the conversation</a>?',
|
||||
),
|
||||
);
|
||||
|
||||
people.add_active_user(me);
|
||||
people.initialize_current_user(me.user_id);
|
||||
set_filter([["pm-with", me.email]]);
|
||||
hide_all_empty_narrow_messages();
|
||||
narrow_banner.show_empty_narrow_message();
|
||||
assert.ok($("#empty_narrow_self_private_message").visible());
|
||||
assert.equal(
|
||||
$(".empty_feed_notice_main").html(),
|
||||
empty_narrow_html(
|
||||
"translated: You have not sent any private messages to yourself yet!",
|
||||
'translated HTML: Why not <a href="#" class="empty_feed_compose_private">start a conversation with yourself</a>?',
|
||||
),
|
||||
);
|
||||
|
||||
set_filter([["pm-with", me.email + "," + alice.email]]);
|
||||
hide_all_empty_narrow_messages();
|
||||
narrow_banner.show_empty_narrow_message();
|
||||
assert.ok($("#empty_narrow_multi_private_message").visible());
|
||||
assert.equal(
|
||||
$(".empty_feed_notice_main").html(),
|
||||
empty_narrow_html(
|
||||
"translated: You have no private messages with these people yet!",
|
||||
'translated HTML: Why not <a href="#" class="empty_feed_compose_private">start the conversation</a>?',
|
||||
),
|
||||
);
|
||||
|
||||
set_filter([["group-pm-with", "alice@example.com"]]);
|
||||
hide_all_empty_narrow_messages();
|
||||
narrow_banner.show_empty_narrow_message();
|
||||
assert.ok($("#empty_narrow_group_private_message").visible());
|
||||
assert.equal(
|
||||
$(".empty_feed_notice_main").html(),
|
||||
empty_narrow_html(
|
||||
"translated: You have no group private messages with this person yet!",
|
||||
'translated HTML: Why not <a href="#" class="empty_feed_compose_private">start the conversation</a>?',
|
||||
),
|
||||
);
|
||||
|
||||
set_filter([["sender", "ray@example.com"]]);
|
||||
hide_all_empty_narrow_messages();
|
||||
narrow_banner.show_empty_narrow_message();
|
||||
assert.ok($("#silent_user").visible());
|
||||
assert.equal(
|
||||
$(".empty_feed_notice_main").html(),
|
||||
empty_narrow_html("translated: You haven't received any messages sent by this user yet!"),
|
||||
);
|
||||
|
||||
set_filter([["sender", "sinwar@example.com"]]);
|
||||
hide_all_empty_narrow_messages();
|
||||
narrow_banner.show_empty_narrow_message();
|
||||
assert.ok($("#non_existing_user").visible());
|
||||
|
||||
const display = $("#empty_search_stop_words_string");
|
||||
|
||||
const items = [];
|
||||
display.append = (html) => {
|
||||
items.push(html);
|
||||
};
|
||||
|
||||
set_filter([["search", "grail"]]);
|
||||
hide_all_empty_narrow_messages();
|
||||
narrow_banner.show_empty_narrow_message();
|
||||
assert.ok($("#empty_search_narrow_message").visible());
|
||||
|
||||
assert.equal(items.length, 2);
|
||||
assert.equal(items[0], " ");
|
||||
assert.equal(items[1].text(), "grail");
|
||||
assert.equal(
|
||||
$(".empty_feed_notice_main").html(),
|
||||
empty_narrow_html("translated: This user does not exist!"),
|
||||
);
|
||||
|
||||
set_filter([
|
||||
["sender", "alice@example.com"],
|
||||
|
@ -204,12 +362,24 @@ run_test("show_empty_narrow_message", () => {
|
|||
]);
|
||||
hide_all_empty_narrow_messages();
|
||||
narrow_banner.show_empty_narrow_message();
|
||||
assert.ok($("#empty_narrow_message").visible());
|
||||
assert.equal(
|
||||
$(".empty_feed_notice_main").html(),
|
||||
empty_narrow_html(
|
||||
"translated: Nothing's been sent here yet!",
|
||||
'translated HTML: Why not <a href="#" class="empty_feed_compose_stream">start the conversation</a>?',
|
||||
),
|
||||
);
|
||||
|
||||
set_filter([["is", "invalid"]]);
|
||||
hide_all_empty_narrow_messages();
|
||||
narrow_banner.show_empty_narrow_message();
|
||||
assert.ok($("#empty_narrow_message").visible());
|
||||
assert.equal(
|
||||
$(".empty_feed_notice_main").html(),
|
||||
empty_narrow_html(
|
||||
"translated: Nothing's been sent here yet!",
|
||||
'translated HTML: Why not <a href="#" class="empty_feed_compose_stream">start the conversation</a>?',
|
||||
),
|
||||
);
|
||||
|
||||
const my_stream = {
|
||||
name: "my stream",
|
||||
|
@ -221,60 +391,93 @@ run_test("show_empty_narrow_message", () => {
|
|||
set_filter([["stream", "my stream"]]);
|
||||
hide_all_empty_narrow_messages();
|
||||
narrow_banner.show_empty_narrow_message();
|
||||
assert.ok($("#empty_narrow_message").visible());
|
||||
assert.equal(
|
||||
$(".empty_feed_notice_main").html(),
|
||||
empty_narrow_html(
|
||||
"translated: Nothing's been sent here yet!",
|
||||
'translated HTML: Why not <a href="#" class="empty_feed_compose_stream">start the conversation</a>?',
|
||||
),
|
||||
);
|
||||
|
||||
set_filter([["stream", ""]]);
|
||||
hide_all_empty_narrow_messages();
|
||||
narrow_banner.show_empty_narrow_message();
|
||||
assert.ok($("#nonsubbed_private_nonexistent_stream_narrow_message").visible());
|
||||
assert.equal(
|
||||
$(".empty_feed_notice_main").html(),
|
||||
empty_narrow_html("translated: This stream does not exist or is private."),
|
||||
);
|
||||
});
|
||||
|
||||
run_test("show_empty_narrow_message_with_search", ({mock_template}) => {
|
||||
page_params.stop_words = [];
|
||||
|
||||
mock_template("empty_feed_notice.hbs", true, (data, html) => html);
|
||||
|
||||
narrow_state.reset_current_filter();
|
||||
set_filter([["search", "grail"]]);
|
||||
hide_all_empty_narrow_messages();
|
||||
narrow_banner.show_empty_narrow_message();
|
||||
assert.match($(".empty_feed_notice_main").html(), /<span>grail<\/span>/);
|
||||
});
|
||||
|
||||
run_test("hide_empty_narrow_message", () => {
|
||||
$(".empty_feed_notice").show();
|
||||
$(".empty_feed_notice_main").html("<div class='empty_feed_notice'>Nothing here</div>");
|
||||
narrow_banner.hide_empty_narrow_message();
|
||||
assert.ok(!$(".empty_feed_notice").visible());
|
||||
assert.equal($(".empty_feed_notice").text(), "never-been-set");
|
||||
});
|
||||
|
||||
run_test("show_search_stopwords", () => {
|
||||
run_test("show_search_stopwords", ({mock_template}) => {
|
||||
page_params.stop_words = ["what", "about"];
|
||||
|
||||
narrow_state.reset_current_filter();
|
||||
let items = [];
|
||||
mock_template("empty_feed_notice.hbs", true, (data, html) => html);
|
||||
|
||||
const display = $("#empty_search_stop_words_string");
|
||||
|
||||
display.append = (html) => {
|
||||
if (html.text) {
|
||||
items.push(html.selector + html.text());
|
||||
}
|
||||
const expected_search_data = {
|
||||
has_stop_word: true,
|
||||
query_words: [
|
||||
{query_word: "what", is_stop_word: true},
|
||||
{query_word: "about", is_stop_word: true},
|
||||
{query_word: "grail", is_stop_word: false},
|
||||
],
|
||||
};
|
||||
|
||||
narrow_state.reset_current_filter();
|
||||
set_filter([["search", "what about grail"]]);
|
||||
hide_all_empty_narrow_messages();
|
||||
narrow_banner.show_empty_narrow_message();
|
||||
assert.ok($("#empty_search_narrow_message").visible());
|
||||
assert.equal(
|
||||
$(".empty_feed_notice_main").html(),
|
||||
empty_narrow_html("translated: No search results", undefined, expected_search_data),
|
||||
);
|
||||
|
||||
assert.equal(items.length, 3);
|
||||
assert.equal(items[0], "<del>what");
|
||||
assert.equal(items[1], "<del>about");
|
||||
assert.equal(items[2], "<span>grail");
|
||||
|
||||
items = [];
|
||||
const expected_stream_search_data = {
|
||||
has_stop_word: true,
|
||||
stream_query: "streamA",
|
||||
query_words: [
|
||||
{query_word: "what", is_stop_word: true},
|
||||
{query_word: "about", is_stop_word: true},
|
||||
{query_word: "grail", is_stop_word: false},
|
||||
],
|
||||
};
|
||||
set_filter([
|
||||
["stream", "streamA"],
|
||||
["search", "what about grail"],
|
||||
]);
|
||||
hide_all_empty_narrow_messages();
|
||||
narrow_banner.show_empty_narrow_message();
|
||||
assert.ok($("#empty_search_narrow_message").visible());
|
||||
assert.equal(
|
||||
$(".empty_feed_notice_main").html(),
|
||||
empty_narrow_html("translated: No search results", undefined, expected_stream_search_data),
|
||||
);
|
||||
|
||||
assert.equal(items.length, 4);
|
||||
assert.equal(items[0], "<span>stream: streamA");
|
||||
assert.equal(items[1], "<del>what");
|
||||
assert.equal(items[2], "<del>about");
|
||||
assert.equal(items[3], "<span>grail");
|
||||
|
||||
items = [];
|
||||
const expected_stream_topic_search_data = {
|
||||
has_stop_word: true,
|
||||
stream_query: "streamA",
|
||||
topic_query: "topicA",
|
||||
query_words: [
|
||||
{query_word: "what", is_stop_word: true},
|
||||
{query_word: "about", is_stop_word: true},
|
||||
{query_word: "grail", is_stop_word: false},
|
||||
],
|
||||
};
|
||||
set_filter([
|
||||
["stream", "streamA"],
|
||||
["topic", "topicA"],
|
||||
|
@ -282,18 +485,19 @@ run_test("show_search_stopwords", () => {
|
|||
]);
|
||||
hide_all_empty_narrow_messages();
|
||||
narrow_banner.show_empty_narrow_message();
|
||||
assert.ok($("#empty_search_narrow_message").visible());
|
||||
|
||||
assert.equal(items.length, 4);
|
||||
assert.equal(items[0], "<span>stream: streamA topic: topicA");
|
||||
assert.equal(items[1], "<del>what");
|
||||
assert.equal(items[2], "<del>about");
|
||||
assert.equal(items[3], "<span>grail");
|
||||
assert.equal(
|
||||
$(".empty_feed_notice_main").html(),
|
||||
empty_narrow_html(
|
||||
"translated: No search results",
|
||||
undefined,
|
||||
expected_stream_topic_search_data,
|
||||
),
|
||||
);
|
||||
});
|
||||
|
||||
run_test("show_invalid_narrow_message", () => {
|
||||
run_test("show_invalid_narrow_message", ({mock_template}) => {
|
||||
narrow_state.reset_current_filter();
|
||||
const display = $("#empty_search_stop_words_string");
|
||||
mock_template("empty_feed_notice.hbs", true, (data, html) => html);
|
||||
|
||||
stream_data.add_sub({name: "streamA", stream_id: 88});
|
||||
stream_data.add_sub({name: "streamB", stream_id: 77});
|
||||
|
@ -304,10 +508,12 @@ run_test("show_invalid_narrow_message", () => {
|
|||
]);
|
||||
hide_all_empty_narrow_messages();
|
||||
narrow_banner.show_empty_narrow_message();
|
||||
assert.ok($("#empty_search_narrow_message").visible());
|
||||
assert.equal(
|
||||
display.text(),
|
||||
"translated: You are searching for messages that belong to more than one stream, which is not possible.",
|
||||
$(".empty_feed_notice_main").html(),
|
||||
empty_narrow_html(
|
||||
"translated: No search results",
|
||||
"translated HTML: <p>You are searching for messages that belong to more than one stream, which is not possible.</p>",
|
||||
),
|
||||
);
|
||||
|
||||
set_filter([
|
||||
|
@ -316,10 +522,12 @@ run_test("show_invalid_narrow_message", () => {
|
|||
]);
|
||||
hide_all_empty_narrow_messages();
|
||||
narrow_banner.show_empty_narrow_message();
|
||||
assert.ok($("#empty_search_narrow_message").visible());
|
||||
assert.equal(
|
||||
display.text(),
|
||||
"translated: You are searching for messages that belong to more than one topic, which is not possible.",
|
||||
$(".empty_feed_notice_main").html(),
|
||||
empty_narrow_html(
|
||||
"translated: No search results",
|
||||
"translated HTML: <p>You are searching for messages that belong to more than one topic, which is not possible.</p>",
|
||||
),
|
||||
);
|
||||
|
||||
people.add_active_user(ray);
|
||||
|
@ -331,10 +539,12 @@ run_test("show_invalid_narrow_message", () => {
|
|||
]);
|
||||
hide_all_empty_narrow_messages();
|
||||
narrow_banner.show_empty_narrow_message();
|
||||
assert.ok($("#empty_search_narrow_message").visible());
|
||||
assert.equal(
|
||||
display.text(),
|
||||
"translated: You are searching for messages that are sent by more than one person, which is not possible.",
|
||||
$(".empty_feed_notice_main").html(),
|
||||
empty_narrow_html(
|
||||
"translated: No search results",
|
||||
"translated HTML: <p>You are searching for messages that are sent by more than one person, which is not possible.</p>",
|
||||
),
|
||||
);
|
||||
});
|
||||
|
||||
|
|
|
@ -154,26 +154,29 @@ async function search_silent_user(page: Page, str: string, item: string): Promis
|
|||
await page.click(".search_icon");
|
||||
await page.waitForSelector("#search_query", {visible: true});
|
||||
await common.select_item_via_typeahead(page, "#search_query", str, item);
|
||||
await page.waitForSelector("#silent_user", {visible: true});
|
||||
await page.waitForSelector(".empty_feed_notice", {visible: true});
|
||||
const expect_message = "You haven't received any messages sent by this user yet!";
|
||||
assert.strictEqual(await common.get_text_from_selector(page, "#silent_user"), expect_message);
|
||||
assert.strictEqual(
|
||||
await common.get_text_from_selector(page, ".empty_feed_notice"),
|
||||
expect_message,
|
||||
);
|
||||
await un_narrow(page);
|
||||
}
|
||||
|
||||
async function expect_non_existing_user(page: Page): Promise<void> {
|
||||
await page.waitForSelector("#non_existing_user", {visible: true});
|
||||
await page.waitForSelector(".empty_feed_notice", {visible: true});
|
||||
const expected_message = "This user does not exist!";
|
||||
assert.strictEqual(
|
||||
await common.get_text_from_selector(page, "#non_existing_user"),
|
||||
await common.get_text_from_selector(page, ".empty_feed_notice"),
|
||||
expected_message,
|
||||
);
|
||||
}
|
||||
|
||||
async function expect_non_existing_users(page: Page): Promise<void> {
|
||||
await page.waitForSelector("#non_existing_users", {visible: true});
|
||||
await page.waitForSelector(".empty_feed_notice", {visible: true});
|
||||
const expected_message = "One or more of these users do not exist!";
|
||||
assert.strictEqual(
|
||||
await common.get_text_from_selector(page, "#non_existing_users"),
|
||||
await common.get_text_from_selector(page, ".empty_feed_notice"),
|
||||
expected_message,
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,67 +1,68 @@
|
|||
import $ from "jquery";
|
||||
import _ from "lodash";
|
||||
|
||||
import {$t} from "./i18n";
|
||||
import {$t, $t_html} from "./i18n";
|
||||
import {narrow_error} from "./narrow_error";
|
||||
import * as narrow_state from "./narrow_state";
|
||||
import {page_params} from "./page_params";
|
||||
import * as people from "./people";
|
||||
import * as stream_data from "./stream_data";
|
||||
|
||||
function set_invalid_narrow_message(invalid_narrow_message) {
|
||||
const search_string_display = $("#empty_search_stop_words_string");
|
||||
search_string_display.text(invalid_narrow_message);
|
||||
}
|
||||
|
||||
function show_search_query() {
|
||||
// when search bar contains multiple filters, only show search queries
|
||||
function retrieve_search_query_data() {
|
||||
// when search bar contains multiple filters, only retrieve search queries
|
||||
const current_filter = narrow_state.filter();
|
||||
const search_query = current_filter.operands("search")[0];
|
||||
const query_words = search_query.split(" ");
|
||||
|
||||
const search_string_display = $("#empty_search_stop_words_string");
|
||||
let query_contains_stop_words = false;
|
||||
|
||||
// Also removes previous search_string if any
|
||||
search_string_display.text($t({defaultMessage: "You searched for:"}));
|
||||
const search_string_result = {
|
||||
query_words: [],
|
||||
has_stop_word: false,
|
||||
};
|
||||
|
||||
// Add in stream:foo and topic:bar if present
|
||||
if (current_filter.has_operator("stream") || current_filter.has_operator("topic")) {
|
||||
let stream_topic_string = "";
|
||||
const stream = current_filter.operands("stream")[0];
|
||||
const topic = current_filter.operands("topic")[0];
|
||||
if (stream) {
|
||||
stream_topic_string = "stream: " + stream;
|
||||
search_string_result.stream_query = stream;
|
||||
}
|
||||
if (topic) {
|
||||
stream_topic_string = stream_topic_string + " topic: " + topic;
|
||||
search_string_result.topic_query = topic;
|
||||
}
|
||||
|
||||
search_string_display.append(" ");
|
||||
search_string_display.append($("<span>").text(stream_topic_string));
|
||||
}
|
||||
|
||||
// Gather information about each query word
|
||||
for (const query_word of query_words) {
|
||||
search_string_display.append(" ");
|
||||
|
||||
// if query contains stop words, it is enclosed by a <del> tag
|
||||
if (page_params.stop_words.includes(query_word)) {
|
||||
// stop_words do not need sanitization so this is unnecessary but it is fail-safe.
|
||||
search_string_display.append($("<del>").text(query_word));
|
||||
query_contains_stop_words = true;
|
||||
search_string_result.has_stop_word = true;
|
||||
search_string_result.query_words.push({
|
||||
query_word,
|
||||
is_stop_word: true,
|
||||
});
|
||||
} else {
|
||||
// We use .text("...") to sanitize the user-given query_string.
|
||||
search_string_display.append($("<span>").text(query_word));
|
||||
search_string_result.query_words.push({
|
||||
query_word,
|
||||
is_stop_word: false,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (query_contains_stop_words) {
|
||||
const preamble = $t({defaultMessage: "Some common words were excluded from your search."});
|
||||
search_string_display.html(_.escape(preamble) + "<br/>" + search_string_display.html());
|
||||
}
|
||||
return search_string_result;
|
||||
}
|
||||
|
||||
function pick_empty_narrow_banner() {
|
||||
const default_banner = $("#empty_narrow_message");
|
||||
const default_banner = {
|
||||
title: $t({defaultMessage: "Nothing's been sent here yet!"}),
|
||||
html: $t_html(
|
||||
{
|
||||
defaultMessage: "Why not <z-link>start the conversation</z-link>?",
|
||||
},
|
||||
{
|
||||
"z-link": (content_html) =>
|
||||
`<a href="#" class="empty_feed_compose_stream">${content_html}</a>`,
|
||||
},
|
||||
),
|
||||
};
|
||||
const empty_search_narrow_title = $t({defaultMessage: "No search results"});
|
||||
|
||||
const current_filter = narrow_state.filter();
|
||||
|
||||
|
@ -78,57 +79,105 @@ function pick_empty_narrow_banner() {
|
|||
// For invalid-multi-operator narrows, we display an invalid narrow message
|
||||
const streams = current_filter.operands("stream");
|
||||
|
||||
let invalid_narrow_message = "";
|
||||
// No message can have multiple streams
|
||||
if (streams.length > 1) {
|
||||
invalid_narrow_message = $t({
|
||||
defaultMessage:
|
||||
"You are searching for messages that belong to more than one stream, which is not possible.",
|
||||
});
|
||||
return {
|
||||
title: empty_search_narrow_title,
|
||||
html: $t_html({
|
||||
defaultMessage:
|
||||
"<p>You are searching for messages that belong to more than one stream, which is not possible.</p>",
|
||||
}),
|
||||
};
|
||||
}
|
||||
// No message can have multiple topics
|
||||
if (current_filter.operands("topic").length > 1) {
|
||||
invalid_narrow_message = $t({
|
||||
defaultMessage:
|
||||
"You are searching for messages that belong to more than one topic, which is not possible.",
|
||||
});
|
||||
return {
|
||||
title: empty_search_narrow_title,
|
||||
html: $t_html({
|
||||
defaultMessage:
|
||||
"<p>You are searching for messages that belong to more than one topic, which is not possible.</p>",
|
||||
}),
|
||||
};
|
||||
}
|
||||
// No message can have multiple senders
|
||||
if (current_filter.operands("sender").length > 1) {
|
||||
invalid_narrow_message = $t({
|
||||
defaultMessage:
|
||||
"You are searching for messages that are sent by more than one person, which is not possible.",
|
||||
});
|
||||
}
|
||||
if (invalid_narrow_message !== "") {
|
||||
set_invalid_narrow_message(invalid_narrow_message);
|
||||
return $("#empty_search_narrow_message");
|
||||
return {
|
||||
title: empty_search_narrow_title,
|
||||
html: $t_html({
|
||||
defaultMessage:
|
||||
"<p>You are searching for messages that are sent by more than one person, which is not possible.</p>",
|
||||
}),
|
||||
};
|
||||
}
|
||||
|
||||
// For empty stream searches within other narrows, we display the stop words
|
||||
if (current_filter.operands("search").length > 0) {
|
||||
show_search_query();
|
||||
return $("#empty_search_narrow_message");
|
||||
return {
|
||||
title: empty_search_narrow_title,
|
||||
search_data: retrieve_search_query_data(),
|
||||
};
|
||||
}
|
||||
|
||||
// For other multi-operator narrows, we just use the default banner
|
||||
return default_banner;
|
||||
}
|
||||
|
||||
switch (first_operator) {
|
||||
case "is":
|
||||
switch (first_operand) {
|
||||
case "starred":
|
||||
// You have no starred messages.
|
||||
return $("#empty_star_narrow_message");
|
||||
return {
|
||||
title: $t({defaultMessage: "You haven't starred anything yet!"}),
|
||||
html: $t_html(
|
||||
{
|
||||
defaultMessage:
|
||||
"Learn more about starring messages <z-link>here</z-link>.",
|
||||
},
|
||||
{
|
||||
"z-link": (content_html) =>
|
||||
`<a href="/help/star-a-message">${content_html}</a>`,
|
||||
},
|
||||
),
|
||||
};
|
||||
case "mentioned":
|
||||
return $("#empty_narrow_all_mentioned");
|
||||
return {
|
||||
title: $t({defaultMessage: "You haven't been mentioned yet!"}),
|
||||
html: $t_html(
|
||||
{
|
||||
defaultMessage: "Learn more about mentions <z-link>here</z-link>.",
|
||||
},
|
||||
{
|
||||
"z-link": (content_html) =>
|
||||
`<a href="/help/mention-a-user-or-group">${content_html}</a>`,
|
||||
},
|
||||
),
|
||||
};
|
||||
case "private":
|
||||
// You have no private messages.
|
||||
return $("#empty_narrow_all_private_message");
|
||||
return {
|
||||
title: $t({defaultMessage: "You have no private messages yet!"}),
|
||||
html: $t_html(
|
||||
{
|
||||
defaultMessage: "Why not <z-link>start the conversation</z-link>?",
|
||||
},
|
||||
{
|
||||
// TODO: The href here is a bit weird; we probably want to migrate
|
||||
// this to a button element down the line.
|
||||
"z-link": (content_html) =>
|
||||
`<a href="#" class="empty_feed_compose_private">${content_html}</a>`,
|
||||
},
|
||||
),
|
||||
};
|
||||
case "unread":
|
||||
// You have no unread messages.
|
||||
return $("#no_unread_narrow_message");
|
||||
return {
|
||||
title: $t({defaultMessage: "You have no unread messages!"}),
|
||||
};
|
||||
case "resolved":
|
||||
return $("#empty_narrow_resolved_topics");
|
||||
return {
|
||||
title: $t({defaultMessage: "No topics are marked as resolved."}),
|
||||
};
|
||||
}
|
||||
// fallthrough to default case if no match is found
|
||||
break;
|
||||
|
@ -149,48 +198,131 @@ function pick_empty_narrow_banner() {
|
|||
}
|
||||
|
||||
if (can_toggle_narrowed_stream()) {
|
||||
return $("#nonsubbed_stream_narrow_message");
|
||||
return {
|
||||
title: $t({
|
||||
defaultMessage:
|
||||
"You aren't subscribed to this stream and nobody has talked about that yet!",
|
||||
}),
|
||||
// TODO: Consider moving the button to be its own option in the template.
|
||||
html: $t_html(
|
||||
{
|
||||
defaultMessage: "<z-button>Subscribe</z-button>",
|
||||
},
|
||||
{
|
||||
"z-button": (content_html) =>
|
||||
`<button class="button white rounded stream_sub_unsub_button sea-green" type="button" name="subscription">${content_html}</button>`,
|
||||
},
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
return $("#nonsubbed_private_nonexistent_stream_narrow_message");
|
||||
return {
|
||||
title: $t({defaultMessage: "This stream does not exist or is private."}),
|
||||
};
|
||||
}
|
||||
// else fallthrough to default case
|
||||
break;
|
||||
case "search":
|
||||
case "search": {
|
||||
// You are narrowed to empty search results.
|
||||
show_search_query();
|
||||
return $("#empty_search_narrow_message");
|
||||
return {
|
||||
title: empty_search_narrow_title,
|
||||
search_data: retrieve_search_query_data(),
|
||||
};
|
||||
}
|
||||
case "pm-with":
|
||||
if (!people.is_valid_bulk_emails_for_compose(first_operand.split(","))) {
|
||||
if (!first_operand.includes(",")) {
|
||||
return $("#non_existing_user");
|
||||
return {
|
||||
title: $t({defaultMessage: "This user does not exist!"}),
|
||||
};
|
||||
}
|
||||
return $("#non_existing_users");
|
||||
return {
|
||||
title: $t({defaultMessage: "One or more of these users do not exist!"}),
|
||||
};
|
||||
}
|
||||
if (!first_operand.includes(",")) {
|
||||
// You have no private messages with this person
|
||||
if (people.is_current_user(first_operand)) {
|
||||
return $("#empty_narrow_self_private_message");
|
||||
return {
|
||||
title: $t({
|
||||
defaultMessage:
|
||||
"You have not sent any private messages to yourself yet!",
|
||||
}),
|
||||
html: $t_html(
|
||||
{
|
||||
defaultMessage:
|
||||
"Why not <z-link>start a conversation with yourself</z-link>?",
|
||||
},
|
||||
{
|
||||
"z-link": (content_html) =>
|
||||
`<a href="#" class="empty_feed_compose_private">${content_html}</a>`,
|
||||
},
|
||||
),
|
||||
};
|
||||
}
|
||||
return $("#empty_narrow_private_message");
|
||||
return {
|
||||
title: $t({
|
||||
defaultMessage: "You have no private messages with this person yet!",
|
||||
}),
|
||||
html: $t_html(
|
||||
{
|
||||
defaultMessage: "Why not <z-link>start the conversation</z-link>?",
|
||||
},
|
||||
{
|
||||
"z-link": (content_html) =>
|
||||
`<a href="#" class="empty_feed_compose_private">${content_html}</a>`,
|
||||
},
|
||||
),
|
||||
};
|
||||
}
|
||||
return $("#empty_narrow_multi_private_message");
|
||||
return {
|
||||
title: $t({defaultMessage: "You have no private messages with these people yet!"}),
|
||||
html: $t_html(
|
||||
{
|
||||
defaultMessage: "Why not <z-link>start the conversation</z-link>?",
|
||||
},
|
||||
{
|
||||
"z-link": (content_html) =>
|
||||
`<a href="#" class="empty_feed_compose_private">${content_html}</a>`,
|
||||
},
|
||||
),
|
||||
};
|
||||
case "sender":
|
||||
if (people.get_by_email(first_operand)) {
|
||||
return $("#silent_user");
|
||||
return {
|
||||
title: $t({
|
||||
defaultMessage: "You haven't received any messages sent by this user yet!",
|
||||
}),
|
||||
};
|
||||
}
|
||||
return $("#non_existing_user");
|
||||
return {
|
||||
title: $t({defaultMessage: "This user does not exist!"}),
|
||||
};
|
||||
case "group-pm-with":
|
||||
return $("#empty_narrow_group_private_message");
|
||||
return {
|
||||
title: $t({
|
||||
defaultMessage: "You have no group private messages with this person yet!",
|
||||
}),
|
||||
html: $t_html(
|
||||
{
|
||||
defaultMessage: "Why not <z-link>start the conversation</z-link>?",
|
||||
},
|
||||
{
|
||||
"z-link": (content_html) =>
|
||||
`<a href="#" class="empty_feed_compose_private">${content_html}</a>`,
|
||||
},
|
||||
),
|
||||
};
|
||||
}
|
||||
return default_banner;
|
||||
}
|
||||
|
||||
export function show_empty_narrow_message() {
|
||||
$(".empty_feed_notice").hide();
|
||||
pick_empty_narrow_banner().show();
|
||||
$(".empty_feed_notice_main").empty();
|
||||
const rendered_narrow_banner = narrow_error(pick_empty_narrow_banner());
|
||||
$(".empty_feed_notice_main").html(rendered_narrow_banner);
|
||||
}
|
||||
|
||||
export function hide_empty_narrow_message() {
|
||||
$(".empty_feed_notice").hide();
|
||||
$(".empty_feed_notice_main").empty();
|
||||
}
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
import render_empty_feed_notice from "../templates/empty_feed_notice.hbs";
|
||||
|
||||
export function narrow_error(narrow_banner_data) {
|
||||
const title = narrow_banner_data.title;
|
||||
const html = narrow_banner_data.html;
|
||||
const search_data = narrow_banner_data.search_data;
|
||||
|
||||
const $empty_feed_notice = render_empty_feed_notice({title, html, search_data});
|
||||
return $empty_feed_notice;
|
||||
}
|
|
@ -2439,7 +2439,6 @@ div.topic_edit_spinner .loading_indicator_spinner {
|
|||
|
||||
.empty_feed_notice {
|
||||
padding: 3em 1em;
|
||||
display: none;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
<div class="empty_feed_notice">
|
||||
<h4> {{ title }} </h4>
|
||||
{{#if (or search_data.query_words search.topic_query search_data.stream_query)}}
|
||||
<div>
|
||||
{{#if search_data.has_stop_word}}{{#tr}}Some common words were excluded from your search.{{/tr}} <br/>{{/if}}{{#tr}}You searched for:{{/tr}}
|
||||
{{#if search_data.stream_query}}
|
||||
<span>stream: {{search_data.stream_query}}</span>
|
||||
{{/if}}
|
||||
{{#if search_data.topic_query}}
|
||||
<span>topic: {{search_data.topic_query}}</span>
|
||||
{{/if}}
|
||||
{{#each search_data.query_words}}
|
||||
{{#if is_stop_word}}
|
||||
<del>{{query_word}}</del>
|
||||
{{else}}
|
||||
<span>{{query_word}}</span>
|
||||
{{/if}}
|
||||
{{/each}}
|
||||
</div>
|
||||
{{else}}
|
||||
{{{ html }}}
|
||||
{{/if}}
|
||||
</div>
|
|
@ -19,113 +19,4 @@
|
|||
{% endtrans %}
|
||||
</p>
|
||||
</div>
|
||||
<div id="empty_narrow_message" class="empty_feed_notice">
|
||||
<h4>{{ _("Nothing's been sent here yet!") }}</h4>
|
||||
|
||||
<p>
|
||||
{% trans %}
|
||||
Why not <a href="#" class="empty_feed_compose_stream">
|
||||
start the conversation</a>?
|
||||
{% endtrans %}
|
||||
</p>
|
||||
</div>
|
||||
<div id="empty_narrow_all_private_message" class="empty_feed_notice">
|
||||
<h4>{{ _('You have no private messages yet!') }}</h4>
|
||||
|
||||
<p>
|
||||
{% trans %}
|
||||
Why not <a href="#" class="empty_feed_compose_private">
|
||||
start the conversation</a>?
|
||||
{% endtrans %}
|
||||
</p>
|
||||
</div>
|
||||
<div id="empty_narrow_private_message" class="empty_feed_notice">
|
||||
<h4>{{ _('You have no private messages with this person yet!') }}</h4>
|
||||
|
||||
<p>
|
||||
{% trans %}
|
||||
Why not <a href="#" class="empty_feed_compose_private">
|
||||
start the conversation</a>?
|
||||
{% endtrans %}
|
||||
</p>
|
||||
</div>
|
||||
<div id="empty_narrow_self_private_message" class="empty_feed_notice">
|
||||
<h4>{{ _('You have not sent any private messages to yourself yet!') }}</h4>
|
||||
|
||||
<p>
|
||||
{% trans %}
|
||||
Why not <a href="#" class="empty_feed_compose_private">
|
||||
start a conversation with yourself</a>?
|
||||
{% endtrans %}
|
||||
</p>
|
||||
</div>
|
||||
<div id="empty_narrow_group_private_message" class="empty_feed_notice">
|
||||
<h4>{{ _('You have no group private messages with this person yet!') }}</h4>
|
||||
|
||||
<p>
|
||||
{% trans %}
|
||||
Why not <a href="#" class="empty_feed_compose_private">
|
||||
start the conversation</a>?
|
||||
{% endtrans %}
|
||||
</p>
|
||||
</div>
|
||||
<div id="empty_narrow_multi_private_message" class="empty_feed_notice">
|
||||
<h4>{{ _('You have no private messages with these people yet!') }}</h4>
|
||||
|
||||
<p>
|
||||
{% trans %}
|
||||
Why not <a href="#" class="empty_feed_compose_private">
|
||||
start the conversation</a>?
|
||||
{% endtrans %}
|
||||
</p>
|
||||
</div>
|
||||
<div id="silent_user" class="empty_feed_notice">
|
||||
<h4>{{ _("You haven't received any messages sent by this user yet!") }}</h4>
|
||||
</div>
|
||||
<div id="non_existing_user" class="empty_feed_notice">
|
||||
<h4>{{ _("This user does not exist!") }}</h4>
|
||||
</div>
|
||||
<div id="non_existing_users" class="empty_feed_notice">
|
||||
<h4>{{ _("One or more of these users do not exist!") }}</h4>
|
||||
</div>
|
||||
<div id="nonsubbed_stream_narrow_message" class="empty_feed_notice">
|
||||
<h4>{{ _("You aren't subscribed to this stream and nobody has talked about that yet!") }}</h4>
|
||||
<div class="sub_button_row new-style">
|
||||
<button class="button white rounded stream_sub_unsub_button sea-green" type="button" name="subscription">
|
||||
{{ _('Subscribe') }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div id="nonsubbed_private_nonexistent_stream_narrow_message" class="empty_feed_notice">
|
||||
<h4>{{ _("This stream does not exist or is private.") }}</h4>
|
||||
</div>
|
||||
<div id="empty_star_narrow_message" class="empty_feed_notice">
|
||||
<h4>{{ _("You haven't starred anything yet!") }}</h4>
|
||||
|
||||
<p>
|
||||
{% trans %}
|
||||
Learn more about starring messages <a href="/help/star-a-message">
|
||||
here</a>.
|
||||
{% endtrans %}
|
||||
</p>
|
||||
</div>
|
||||
<div id="no_unread_narrow_message" class="empty_feed_notice">
|
||||
<h4>{{ _("You have no unread messages!") }}</h4>
|
||||
</div>
|
||||
<div id="empty_narrow_all_mentioned" class="empty_feed_notice">
|
||||
<h4>{{ _("You haven't been mentioned yet!") }}</h4>
|
||||
|
||||
<p>
|
||||
{% trans %}
|
||||
Learn more about mentions <a href="/help/mention-a-user-or-group">
|
||||
here</a>.
|
||||
{% endtrans %}
|
||||
</p>
|
||||
</div>
|
||||
<div id="empty_search_narrow_message" class="empty_feed_notice">
|
||||
<h4>{{ _('No search results') }}</h4>
|
||||
<p><span id="empty_search_stop_words_string" class="empty_search_text"></span></p>
|
||||
</div>
|
||||
<div id="empty_narrow_resolved_topics" class="empty_feed_notice">
|
||||
<h4>{{ _("No topics are marked as resolved.") }}</h4>
|
||||
</div>
|
||||
<div class="empty_feed_notice_main"></div>
|
||||
|
|
|
@ -219,7 +219,7 @@ class HomeTest(ZulipTestCase):
|
|||
def test_home(self) -> None:
|
||||
# Keep this list sorted!!!
|
||||
html_bits = [
|
||||
"start the conversation",
|
||||
"empty_feed_notice_main",
|
||||
"Loading...",
|
||||
# Verify that the app styles get included
|
||||
"app-stubentry.js",
|
||||
|
@ -446,7 +446,7 @@ class HomeTest(ZulipTestCase):
|
|||
which still want the home page to load properly.
|
||||
"""
|
||||
html = result.content.decode()
|
||||
if "start a conversation" not in html:
|
||||
if "empty_feed_notice_main" not in html:
|
||||
raise AssertionError("Home page probably did not load.")
|
||||
|
||||
def test_terms_of_service(self) -> None:
|
||||
|
|
Loading…
Reference in New Issue