FIX: empty state message on the user bookmarks page (#14257)

After adding an empty state banner to the user bookmarks page, we have found the bug. Steps to reproduce:

- Go to the user bookmarks page
- Search for something that doesn’t exist in bookmarks
- Click again Bookmarked on the sidebar or View All Bookmarks on the user menu again
This commit is contained in:
Andrei Prigorshnev 2021-10-04 16:48:45 +04:00 committed by GitHub
parent 149e869c22
commit 9f626f2735
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 97 additions and 94 deletions

View File

@ -3,42 +3,31 @@ import { iconHTML } from "discourse-common/lib/icon-library";
import Bookmark from "discourse/models/bookmark";
import I18n from "I18n";
import { Promise } from "rsvp";
import EmberObject, { action } from "@ember/object";
import EmberObject, { action, computed } from "@ember/object";
import discourseComputed from "discourse-common/utils/decorators";
import { notEmpty } from "@ember/object/computed";
import { equal, notEmpty } from "@ember/object/computed";
import { ajax } from "discourse/lib/ajax";
export default Controller.extend({
queryParams: ["q"],
q: null,
application: controller(),
user: controller(),
content: null,
loading: false,
loadingMore: false,
permissionDenied: false,
searchTerm: null,
q: null,
inSearchMode: notEmpty("q"),
noContent: equal("model.bookmarks.length", 0),
loadItems() {
this.setProperties({
content: [],
loading: true,
permissionDenied: false,
searchTerm: this.q,
});
return this.model
.loadItems({ q: this.q })
.then((response) => this._processLoadResponse(response))
.catch(() => this._bookmarksListDenied())
.finally(() => {
this.setProperties({
loaded: true,
loading: false,
});
});
searchTerm: computed("q", {
get() {
return this.q;
},
set(key, value) {
return value;
},
}),
@discourseComputed()
emptyStateBody() {
@ -57,20 +46,16 @@ export default Controller.extend({
return inSearchMode && noContent;
},
@discourseComputed("loaded", "content.length")
noContent(loaded, contentLength) {
return loaded && contentLength === 0;
},
@action
search() {
this.set("q", this.searchTerm);
this.loadItems();
this.transitionToRoute({
queryParams: { q: this.searchTerm },
});
},
@action
reload() {
this.loadItems();
this.send("triggerRefresh");
},
@action
@ -81,13 +66,27 @@ export default Controller.extend({
this.set("loadingMore", true);
return this.model
.loadMore({ q: this.q })
return this._loadMoreBookmarks(this.q)
.then((response) => this._processLoadResponse(response))
.catch(() => this._bookmarksListDenied())
.finally(() => this.set("loadingMore", false));
},
_loadMoreBookmarks(searchQuery) {
if (!this.model.loadMoreUrl) {
return Promise.resolve();
}
let moreUrl = this.model.loadMoreUrl;
if (searchQuery) {
const delimiter = moreUrl.includes("?") ? "&" : "?";
const q = encodeURIComponent(searchQuery);
moreUrl += `${delimiter}q=${q}`;
}
return ajax({ url: moreUrl });
},
_bookmarksListDenied() {
this.set("permissionDenied", true);
},
@ -98,10 +97,15 @@ export default Controller.extend({
}
response = response.user_bookmark_list;
this.model.more_bookmarks_url = response.more_bookmarks_url;
this.model.loadMoreUrl = response.more_bookmarks_url;
if (response.bookmarks) {
const bookmarkModels = response.bookmarks.map((bookmark) => {
const bookmarkModels = response.bookmarks.map(this.transform);
this.model.bookmarks.pushObjects(bookmarkModels);
}
},
transform(bookmark) {
const bookmarkModel = Bookmark.create(bookmark);
bookmarkModel.topicStatus = EmberObject.create({
closed: bookmark.closed,
@ -112,8 +116,5 @@ export default Controller.extend({
invisible: bookmark.invisible,
});
return bookmarkModel;
});
this.content.pushObjects(bookmarkModels);
}
},
});

View File

@ -141,40 +141,6 @@ const Bookmark = RestModel.extend({
});
},
loadItems(params) {
let url = `/u/${this.user.username}/bookmarks.json`;
if (params) {
url += "?" + $.param(params);
}
return ajax(url);
},
loadMore(additionalParams) {
if (!this.more_bookmarks_url) {
return Promise.resolve();
}
let moreUrl = this.more_bookmarks_url;
if (moreUrl) {
let [url, params] = moreUrl.split("?");
moreUrl = url;
if (params) {
moreUrl += "?" + params;
}
if (additionalParams) {
if (moreUrl.includes("?")) {
moreUrl += "&" + $.param(additionalParams);
} else {
moreUrl += "?" + $.param(additionalParams);
}
}
}
return ajax({ url: moreUrl });
},
@discourseComputed(
"post_user_username",
"post_user_avatar_template",

View File

@ -1,27 +1,63 @@
import DiscourseRoute from "discourse/routes/discourse";
import { ajax } from "discourse/lib/ajax";
import { action } from "@ember/object";
export default DiscourseRoute.extend({
queryParams: {
acting_username: { refreshModel: true },
q: { refreshModel: true },
},
model() {
return this.modelFor("user").get("bookmarks");
model(params) {
const controller = this.controllerFor("user-activity-bookmarks");
return this._loadBookmarks(params)
.then((response) => {
if (!response.user_bookmark_list) {
return { bookmarks: [] };
}
const bookmarks = response.user_bookmark_list.bookmarks.map(
controller.transform
);
const loadMoreUrl = response.user_bookmark_list.more_bookmarks_url;
return { bookmarks, loadMoreUrl };
})
.catch(() => controller.set("permissionDenied", true));
},
renderTemplate() {
this.render("user_bookmarks");
},
setupController(controller, model) {
controller.set("model", model);
controller.loadItems();
},
actions: {
@action
didTransition() {
this.controllerFor("user-activity")._showFooter();
return true;
},
@action
loading(transition) {
let controller = this.controllerFor("user-activity-bookmarks");
controller.set("loading", true);
transition.promise.finally(function () {
controller.set("loading", false);
});
},
@action
triggerRefresh() {
this.refresh();
},
_loadBookmarks(params) {
let url = `/u/${this.modelFor("user").username}/bookmarks.json`;
if (params) {
url += "?" + $.param(params);
}
return ajax(url);
},
});

View File

@ -29,7 +29,7 @@
loadMore=(action "loadMore")
reload=(action "reload")
loadingMore=loadingMore
content=content
content=model.bookmarks
}}
{{/if}}
{{/if}}