FEATURE: improve "blank page syndrome" on the user bookmarks page

This commit is contained in:
Andrei Prigorshnev 2021-08-20 00:08:59 +04:00 committed by GitHub
parent 2bbc97fda5
commit d1781e4c7d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 72 additions and 51 deletions

View File

@ -1,27 +1,30 @@
import Controller, { inject as controller } from "@ember/controller"; import Controller, { inject as controller } from "@ember/controller";
import { iconHTML } from "discourse-common/lib/icon-library";
import Bookmark from "discourse/models/bookmark"; import Bookmark from "discourse/models/bookmark";
import I18n from "I18n"; import I18n from "I18n";
import { Promise } from "rsvp"; import { Promise } from "rsvp";
import EmberObject, { action } from "@ember/object"; import EmberObject, { action } from "@ember/object";
import discourseComputed from "discourse-common/utils/decorators"; import discourseComputed from "discourse-common/utils/decorators";
import { notEmpty } from "@ember/object/computed";
export default Controller.extend({ export default Controller.extend({
queryParams: ["q"],
application: controller(), application: controller(),
user: controller(), user: controller(),
content: null, content: null,
loading: false, loading: false,
noResultsHelp: null, permissionDenied: false,
searchTerm: null, searchTerm: null,
q: null, q: null,
inSearchMode: notEmpty("q"),
queryParams: ["q"],
loadItems() { loadItems() {
this.setProperties({ this.setProperties({
content: [], content: [],
loading: true, loading: true,
noResultsHelp: null, permissionDenied: false,
}); });
if (this.q && !this.searchTerm) { if (this.q && !this.searchTerm) {
@ -40,22 +43,28 @@ export default Controller.extend({
}); });
}, },
@discourseComputed()
emptyStateBody() {
return I18n.t("user.no_bookmarks_body", {
icon: iconHTML("bookmark"),
}).htmlSafe();
},
@discourseComputed("inSearchMode", "noContent")
userDoesNotHaveBookmarks(inSearchMode, noContent) {
return !inSearchMode && noContent;
},
@discourseComputed("inSearchMode", "noContent")
nothingFound(inSearchMode, noContent) {
return inSearchMode && noContent;
},
@discourseComputed("loaded", "content.length") @discourseComputed("loaded", "content.length")
noContent(loaded, contentLength) { noContent(loaded, contentLength) {
return loaded && contentLength === 0; return loaded && contentLength === 0;
}, },
@discourseComputed("noResultsHelp", "noContent")
noResultsHelpMessage(noResultsHelp, noContent) {
if (noResultsHelp) {
return noResultsHelp;
}
if (noContent) {
return I18n.t("bookmarks.no_user_bookmarks");
}
return "";
},
@action @action
search() { search() {
this.set("q", this.searchTerm); this.set("q", this.searchTerm);
@ -83,16 +92,11 @@ export default Controller.extend({
}, },
_bookmarksListDenied() { _bookmarksListDenied() {
this.set("noResultsHelp", I18n.t("bookmarks.list_permission_denied")); this.set("permissionDenied", true);
}, },
_processLoadResponse(response) { _processLoadResponse(response) {
if (!response) { if (!response || !response.user_bookmark_list) {
return;
}
if (response.no_results_help) {
this.set("noResultsHelp", response.no_results_help);
return; return;
} }

View File

@ -1,22 +1,34 @@
<div class="form-horizontal bookmark-search-form"> {{#conditional-loading-spinner condition=loading}}
{{input type="text" {{#if permissionDenied}}
value=searchTerm <div class="alert alert-info">{{i18n "bookmarks.list_permission_denied"}}</div>
placeholder=(i18n "bookmarks.search_placeholder") {{else if userDoesNotHaveBookmarks}}
enter=(action "search") <div class="empty-state">
id="bookmark-search" autocomplete="discourse"}} <span class="empty-state-title">{{i18n "user.no_bookmarks_title"}}</span>
{{d-button <div class="empty-state-body">
class="btn-primary" <p>{{emptyStateBody}}</p>
action=(action "search") </div>
type="button" </div>
icon="search"}} {{else}}
</div> <div class="form-horizontal bookmark-search-form">
{{#if noContent}} {{input type="text"
<div class="alert alert-info">{{noResultsHelpMessage}}</div> value=searchTerm
{{else}} placeholder=(i18n "bookmarks.search_placeholder")
{{bookmark-list enter=(action "search")
loadMore=(action "loadMore") id="bookmark-search" autocomplete="discourse"}}
reload=(action "reload") {{d-button
loading=loading class="btn-primary"
loadingMore=loadingMore action=(action "search")
content=content}} type="button"
{{/if}} icon="search"}}
</div>
{{#if nothingFound}}
<div class="alert alert-info">{{i18n "user.no_bookmarks_search"}}</div>
{{else}}
{{bookmark-list
loadMore=(action "loadMore")
reload=(action "reload")
loadingMore=loadingMore
content=content}}
{{/if}}
{{/if}}
{{/conditional-loading-spinner}}

View File

@ -1,8 +1,4 @@
import { import { acceptance, exists } from "discourse/tests/helpers/qunit-helpers";
acceptance,
exists,
queryAll,
} from "discourse/tests/helpers/qunit-helpers";
import { click, visit } from "@ember/test-helpers"; import { click, visit } from "@ember/test-helpers";
import { cloneJSON } from "discourse-common/lib/object"; import { cloneJSON } from "discourse-common/lib/object";
import selectKit from "discourse/tests/helpers/select-kit-helper"; import selectKit from "discourse/tests/helpers/select-kit-helper";
@ -22,6 +18,11 @@ acceptance("User's bookmarks", function (needs) {
assert.not(exists(".bootbox.modal"), "it should not show the modal"); assert.not(exists(".bootbox.modal"), "it should not show the modal");
}); });
test("it renders search controls if there are bookmarks", async function (assert) {
await visit("/u/eviltrout/activity/bookmarks");
assert.ok(exists("div.bookmark-search-form"));
});
}); });
acceptance("User's bookmarks - reminder", function (needs) { acceptance("User's bookmarks - reminder", function (needs) {
@ -55,13 +56,16 @@ acceptance("User's bookmarks - no bookmarks", function (needs) {
server.get("/u/eviltrout/bookmarks.json", () => server.get("/u/eviltrout/bookmarks.json", () =>
helper.response({ helper.response({
bookmarks: [], bookmarks: [],
no_results_help: "no bookmarks",
}) })
); );
}); });
test("listing users bookmarks - no bookmarks", async function (assert) { test("listing users bookmarks - no bookmarks", async function (assert) {
await visit("/u/eviltrout/activity/bookmarks"); await visit("/u/eviltrout/activity/bookmarks");
assert.equal(queryAll(".alert.alert-info").text(), "no bookmarks"); assert.notOk(
exists("div.bookmark-search-form"),
"does not render search controls"
);
assert.ok(exists("div.empty-state", "renders the empty-state message"));
}); });
}); });

View File

@ -1067,6 +1067,7 @@ en:
no_bookmarks_title: "You haven’t bookmarked anything yet" no_bookmarks_title: "You haven’t bookmarked anything yet"
no_bookmarks_body: > no_bookmarks_body: >
Start bookmarking posts with the %{icon} button and they will be listed here for easy reference. You can schedule a reminder too! Start bookmarking posts with the %{icon} button and they will be listed here for easy reference. You can schedule a reminder too!
no_bookmarks_search: "No bookmarks found with the provided search query."
no_notifications_title: "You don’t have any notifications yet" no_notifications_title: "You don’t have any notifications yet"
no_notifications_body: > no_notifications_body: >
You will be notified in this panel about activity directly relevant to you, including replies to your topics and posts, when someone <b>@mentions</b> you or quotes you, and replies to topics you are watching. Notifications will also be sent to your email when you haven’t logged in for a while. You will be notified in this panel about activity directly relevant to you, including replies to your topics and posts, when someone <b>@mentions</b> you or quotes you, and replies to topics you are watching. Notifications will also be sent to your email when you haven’t logged in for a while.