FEATURE: improve blank page syndrome on the activity/topics, activity/read and group messages pages (#14313)

This commit is contained in:
Andrei Prigorshnev 2021-09-16 22:24:27 +04:00 committed by GitHub
parent d5424161f8
commit 804274af47
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 136 additions and 19 deletions

View File

@ -20,9 +20,9 @@ export default Controller.extend(BulkTopicSelection, {
tagsForUser: null,
incomingCount: reads("pmTopicTrackingState.newIncoming.length"),
@discourseComputed("emptyState", "model.topics.length", "incomingCount")
showEmptyStatePlaceholder(emptyState, topicsLength, incomingCount) {
return emptyState && topicsLength === 0 && incomingCount === 0;
@discourseComputed("model.topics.length", "incomingCount")
noContent(topicsLength, incomingCount) {
return topicsLength === 0 && incomingCount === 0;
},
saveScrollPosition() {

View File

@ -14,7 +14,14 @@ export default (type) => {
if (this._isArchive()) {
filter = `${filter}/archive`;
}
return this.store.findFiltered("topicList", { filter });
return this.store.findFiltered("topicList", { filter }).then((model) => {
// andrei: we agreed that this is an anti pattern,
// it's better to avoid mutating a rest model like this
// this place we'll be refactored later
// see https://github.com/discourse/discourse/pull/14313#discussion_r708784704
model.set("emptyState", this.emptyState());
return model;
});
},
setupController() {
@ -40,6 +47,13 @@ export default (type) => {
});
},
emptyState() {
return {
title: I18n.t("no_group_messages_title"),
body: "",
};
},
_isArchive() {
return type === "archive";
},

View File

@ -40,7 +40,16 @@ export default (inboxType, path, filter) => {
return lastTopicList
? lastTopicList
: this.store.findFiltered("topicList", { filter: topicListFilter });
: this.store
.findFiltered("topicList", { filter: topicListFilter })
.then((model) => {
// andrei: we agreed that this is an anti pattern,
// it's better to avoid mutating a rest model like this
// this place we'll be refactored later
// see https://github.com/discourse/discourse/pull/14313#discussion_r708784704
model.set("emptyState", this.emptyState());
return model;
});
},
setupController() {
@ -61,7 +70,6 @@ export default (inboxType, path, filter) => {
filter: filter,
group: null,
inbox: inboxType,
emptyState: this.emptyState(),
});
userTopicsListController.subscribe();

View File

@ -1,16 +1,38 @@
import UserAction from "discourse/models/user-action";
import UserTopicListRoute from "discourse/routes/user-topic-list";
import { action } from "@ember/object";
import { iconHTML } from "discourse-common/lib/icon-library";
import getURL from "discourse-common/lib/get-url";
import I18n from "I18n";
export default UserTopicListRoute.extend({
userActionType: UserAction.TYPES.topics,
model() {
return this.store.findFiltered("topicList", {
return this.store
.findFiltered("topicList", {
filter: "read",
})
.then((model) => {
// andrei: we agreed that this is an anti pattern,
// it's better to avoid mutating a rest model like this
// this place we'll be refactored later
// see https://github.com/discourse/discourse/pull/14313#discussion_r708784704
model.set("emptyState", this.emptyState());
return model;
});
},
emptyState() {
const title = I18n.t("user_activity.no_read_topics_title");
const body = I18n.t("user_activity.no_read_topics_body", {
topUrl: getURL("/top"),
categoriesUrl: getURL("/categories"),
searchIcon: iconHTML("search"),
}).htmlSafe();
return { title, body };
},
@action
refresh() {
this.refresh();

View File

@ -1,17 +1,34 @@
import UserAction from "discourse/models/user-action";
import UserTopicListRoute from "discourse/routes/user-topic-list";
import { action } from "@ember/object";
import I18n from "I18n";
export default UserTopicListRoute.extend({
userActionType: UserAction.TYPES.topics,
model: function () {
return this.store.findFiltered("topicList", {
return this.store
.findFiltered("topicList", {
filter:
"topics/created-by/" + this.modelFor("user").get("username_lower"),
})
.then((model) => {
// andrei: we agreed that this is an anti pattern,
// it's better to avoid mutating a rest model like this
// this place we'll be refactored later
// see https://github.com/discourse/discourse/pull/14313#discussion_r708784704
model.set("emptyState", this.emptyState());
return model;
});
},
emptyState() {
return {
title: I18n.t("user_activity.no_topics_title"),
body: "",
};
},
@action
refresh() {
this.refresh();

View File

@ -1,8 +1,8 @@
{{#if showEmptyStatePlaceholder}}
{{#if noContent}}
<div class="empty-state">
<span class="empty-state-title">{{emptyState.title}}</span>
<span class="empty-state-title">{{model.emptyState.title}}</span>
<div class="empty-state-body">
<p>{{emptyState.body}}</p>
<p>{{model.emptyState.body}}</p>
</div>
</div>
{{else}}

View File

@ -2,6 +2,7 @@ import {
acceptance,
count,
exists,
query,
queryAll,
} from "discourse/tests/helpers/qunit-helpers";
import { click, visit } from "@ember/test-helpers";
@ -227,9 +228,9 @@ acceptance("Group - Authenticated", function (needs) {
await click(".nav-pills li a[title='Messages']");
assert.equal(
queryAll(".alert").text().trim(),
I18n.t("choose_topic.none_found"),
"it should display the right alert"
query("span.empty-state-title").innerText.trim(),
I18n.t("no_group_messages_title"),
"it should display the right text"
);
});

View File

@ -0,0 +1,24 @@
import { acceptance, exists } from "../helpers/qunit-helpers";
import { test } from "qunit";
import { visit } from "@ember/test-helpers";
acceptance("User Activity / Read - empty state", function (needs) {
needs.user();
needs.pretender((server, helper) => {
const emptyResponse = {
topic_list: {
topics: [],
},
};
server.get("/read.json", () => {
return helper.response(emptyResponse);
});
});
test("It renders the empty state panel", async function (assert) {
await visit("/u/charlie/activity/read");
assert.ok(exists("div.empty-state"));
});
});

View File

@ -0,0 +1,24 @@
import { acceptance, exists } from "../helpers/qunit-helpers";
import { test } from "qunit";
import { visit } from "@ember/test-helpers";
acceptance("User Activity / Topics - empty state", function (needs) {
needs.user();
needs.pretender((server, helper) => {
const emptyResponse = {
topic_list: {
topics: [],
},
};
server.get("/topics/created-by/:username.json", () => {
return helper.response(emptyResponse);
});
});
test("It renders the empty state panel", async function (assert) {
await visit("/u/charlie/activity/topics");
assert.ok(exists("div.empty-state"));
});
});

View File

@ -3866,6 +3866,13 @@ en:
no_likes_title: "You havent liked any topics yet"
no_likes_body: "A great way to jump in and start contributing is to start reading conversations that have already taken place, and select the %{heartIcon} on posts that you like!"
no_likes_others: "No liked posts."
no_topics_title: "You have not started any topics yet"
no_read_topics_title: "You havent read any topics yet"
no_read_topics_body: "Once you start reading discussions, youll see a list here. To start reading, look for topics that interest you in <a href='%{topUrl}'>Top</a> or <a href='%{categoriesUrl}'>Categories</a> or search by keyword %{searchIcon}"
no_group_messages_title: "No group messages found"
# This section is exported to the javascript for i18n in the admin section
admin_js: