FIX: Add bookmark-list component (#10451)

Moving the bookmark list into its own component to solve click binding issues for external links, because controllers are not the place for DOM manipulation!
This commit is contained in:
Martin Brennan 2020-08-18 12:15:00 +10:00 committed by GitHub
parent ba9fbb3443
commit bb74ccf288
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 148 additions and 147 deletions

View File

@ -0,0 +1,60 @@
import Component from "@ember/component";
import I18n from "I18n";
import { action } from "@ember/object";
import showModal from "discourse/lib/show-modal";
import {
shouldOpenInNewTab,
openLinkInNewTab
} from "discourse/lib/click-track";
export default Component.extend({
classNames: ["bookmark-list-wrapper"],
@action
removeBookmark(bookmark) {
const deleteBookmark = () => {
return bookmark
.destroy()
.then(() => this._removeBookmarkFromList(bookmark));
};
if (!bookmark.reminder_at) {
return deleteBookmark();
}
bootbox.confirm(I18n.t("bookmarks.confirm_delete"), result => {
if (result) {
return deleteBookmark();
}
});
},
@action
screenExcerptForExternalLink(event) {
if (event.target && event.target.tagName === "A") {
let link = event.target;
if (shouldOpenInNewTab(link.href)) {
openLinkInNewTab(link);
}
}
},
@action
editBookmark(bookmark) {
let controller = showModal("bookmark", {
model: {
postId: bookmark.post_id,
id: bookmark.id,
reminderAt: bookmark.reminder_at,
name: bookmark.name
},
title: "post.bookmarks.edit",
modalClass: "bookmark-with-reminder"
});
controller.setProperties({
afterSave: () => this.reload()
});
},
_removeBookmarkFromList(bookmark) {
this.content.removeObject(bookmark);
}
});

View File

@ -1,16 +1,10 @@
import I18n from "I18n";
import { schedule } from "@ember/runloop";
import Controller from "@ember/controller";
import showModal from "discourse/lib/show-modal";
import { Promise } from "rsvp";
import { inject } from "@ember/controller";
import { action } from "@ember/object";
import discourseComputed from "discourse-common/utils/decorators";
import Bookmark from "discourse/models/bookmark";
import {
shouldOpenInNewTab,
openLinkInNewTab
} from "discourse/lib/click-track";
export default Controller.extend({
application: inject(),
@ -24,11 +18,6 @@ export default Controller.extend({
queryParams: ["q"],
init() {
this._super(...arguments);
this._boundClick = false;
},
loadItems() {
this.setProperties({
content: [],
@ -40,26 +29,6 @@ export default Controller.extend({
this.set("searchTerm", this.q);
}
if (!this._boundClick) {
schedule("afterRender", () => {
// TODO(martin): This should be pulled out into a bookmark-list component,
// the controller is not the best place for this.
let wrapper = document.querySelector(".bookmark-list-wrapper");
if (!wrapper) {
return;
}
wrapper.addEventListener("click", function(e) {
if (e.target && e.target.tagName === "A") {
let link = e.target;
if (shouldOpenInNewTab(link.href)) {
openLinkInNewTab(link);
}
}
});
this._boundClick = true;
});
}
return this.model
.loadItems({ q: this.searchTerm })
.then(response => this._processLoadResponse(response))
@ -77,10 +46,6 @@ export default Controller.extend({
return loaded && contentLength === 0 && noResultsHelp;
},
_removeBookmarkFromList(bookmark) {
this.content.removeObject(bookmark);
},
@action
search() {
this.set("q", this.searchTerm);
@ -88,37 +53,8 @@ export default Controller.extend({
},
@action
removeBookmark(bookmark) {
const deleteBookmark = () => {
return bookmark
.destroy()
.then(() => this._removeBookmarkFromList(bookmark));
};
if (!bookmark.reminder_at) {
return deleteBookmark();
}
bootbox.confirm(I18n.t("bookmarks.confirm_delete"), result => {
if (result) {
return deleteBookmark();
}
});
},
@action
editBookmark(bookmark) {
let controller = showModal("bookmark", {
model: {
postId: bookmark.post_id,
id: bookmark.id,
reminderAt: bookmark.reminder_at,
name: bookmark.name
},
title: "post.bookmarks.edit",
modalClass: "bookmark-with-reminder"
});
controller.setProperties({
afterSave: () => this.loadItems()
});
reload() {
this.loadItems();
},
@action

View File

@ -0,0 +1,80 @@
{{#conditional-loading-spinner condition=loading}}
{{#load-more selector=".bookmark-list .bookmark-list-item" action=loadMore}}
<table class="topic-list bookmark-list">
<thead>
{{#if site.mobileView}}
<th>&nbsp;</th>
<th>{{i18n "topic.title"}}</th>
<th>&nbsp;</th>
{{else}}
<th>{{i18n "topic.title"}}</th>
<th>&nbsp;</th>
<th class="post-metadata">{{i18n "post.bookmarks.updated"}}</th>
<th class="post-metadata">{{i18n "activity"}}</th>
<th>&nbsp;</th>
{{/if}}
</thead>
<tbody>
{{#each content as |bookmark|}}
<tr class="topic-list-item bookmark-list-item">
{{#if site.mobileView}}
<td>
{{#if bookmark.post_user_avatar_template}}
<a href={{bookmark.postUser.path}} data-user-card={{bookmark.post_user_username}}>
{{avatar bookmark.postUser avatarTemplatePath="avatar_template" usernamePath="username" namePath="name" imageSize="small"}}
</a>
{{/if}}
</td>
{{/if}}
<td class="main-link">
<span class="link-top-line">
<div class="bookmark-metadata">
{{#if bookmark.name}}
<span class="bookmark-metadata-item">
{{d-icon "info-circle"}}{{bookmark.name}}
</span>
{{/if}}
{{#if bookmark.reminder_at}}
<span class="bookmark-metadata-item">
{{d-icon "far-clock"}}{{bookmark.formattedReminder}}
</span>
{{/if}}
</div>
{{topic-status topic=bookmark}}
{{topic-link bookmark}}
</span>
{{#if bookmark.excerpt}}
{{!-- template-lint-disable --}}
<p class="post-excerpt" {{on "click" this.screenExcerptForExternalLink}}>{{html-safe bookmark.excerpt}}</p>
{{/if}}
<div class="link-bottom-line">
{{category-link bookmark.category}}
{{discourse-tags bookmark mode="list" tagsForUser=tagsForUser}}
</div>
</td>
{{#unless site.mobileView}}
<td>
{{#if bookmark.post_user_avatar_template}}
<a href={{bookmark.postUser.path}} data-user-card={{bookmark.post_user_username}}>
{{avatar bookmark.postUser avatarTemplatePath="avatar_template" usernamePath="username" namePath="name" imageSize="small"}}
</a>
{{/if}}
</td>
<td class="post-metadata">{{format-date bookmark.updated_at format="tiny"}}</td>
{{raw "list/activity-column" topic=bookmark class="num post-metadata" tagName="td"}}
{{/unless}}
<td>
{{bookmark-actions-dropdown
bookmark=bookmark
removeBookmark=(action "removeBookmark")
editBookmark=(action "editBookmark")
}}
</td>
</tr>
{{/each}}
</tbody>
</table>
{{conditional-loading-spinner condition=loadingMore}}
{{/load-more}}
{{/conditional-loading-spinner}}

View File

@ -13,85 +13,10 @@
{{#if noContent}}
<div class="alert alert-info">{{noResultsHelp}}</div>
{{else}}
<div class="bookmark-list-wrapper">
{{#conditional-loading-spinner condition=loading}}
{{#load-more selector=".bookmark-list .bookmark-list-item" action=(action "loadMore")}}
<table class="topic-list bookmark-list">
<thead>
{{#if site.mobileView}}
<th>&nbsp;</th>
<th>{{i18n "topic.title"}}</th>
<th>&nbsp;</th>
{{else}}
<th>{{i18n "topic.title"}}</th>
<th>&nbsp;</th>
<th class="post-metadata">{{i18n "post.bookmarks.updated"}}</th>
<th class="post-metadata">{{i18n "activity"}}</th>
<th>&nbsp;</th>
{{/if}}
</thead>
<tbody>
{{#each content as |bookmark|}}
<tr class="topic-list-item bookmark-list-item">
{{#if site.mobileView}}
<td>
{{#if bookmark.post_user_avatar_template}}
<a href={{bookmark.postUser.path}} data-user-card={{bookmark.post_user_username}}>
{{avatar bookmark.postUser avatarTemplatePath="avatar_template" usernamePath="username" namePath="name" imageSize="small"}}
</a>
{{/if}}
</td>
{{/if}}
<td class="main-link">
<span class="link-top-line">
<div class="bookmark-metadata">
{{#if bookmark.name}}
<span class="bookmark-metadata-item">
{{d-icon "info-circle"}}{{bookmark.name}}
</span>
{{/if}}
{{#if bookmark.reminder_at}}
<span class="bookmark-metadata-item">
{{d-icon "far-clock"}}{{bookmark.formattedReminder}}
</span>
{{/if}}
</div>
{{topic-status topic=bookmark}}
{{topic-link bookmark}}
</span>
{{#if bookmark.excerpt}}
<p class="post-excerpt">{{html-safe bookmark.excerpt}}</p>
{{/if}}
<div class="link-bottom-line">
{{category-link bookmark.category}}
{{discourse-tags bookmark mode="list" tagsForUser=tagsForUser}}
</div>
</td>
{{#unless site.mobileView}}
<td>
{{#if bookmark.post_user_avatar_template}}
<a href={{bookmark.postUser.path}} data-user-card={{bookmark.post_user_username}}>
{{avatar bookmark.postUser avatarTemplatePath="avatar_template" usernamePath="username" namePath="name" imageSize="small"}}
</a>
{{/if}}
</td>
<td class="post-metadata">{{format-date bookmark.updated_at format="tiny"}}</td>
{{raw "list/activity-column" topic=bookmark class="num post-metadata" tagName="td"}}
{{/unless}}
<td>
{{bookmark-actions-dropdown
bookmark=bookmark
removeBookmark=(action "removeBookmark")
editBookmark=(action "editBookmark")
}}
</td>
</tr>
{{/each}}
</tbody>
</table>
{{conditional-loading-spinner condition=loadingMore}}
{{/load-more}}
{{/conditional-loading-spinner}}
</div>
{{bookmark-list
loadMore=(action "loadMore")
reload=(action "reload")
loading=loading
loadingMore=loadingMore
content=content}}
{{/if}}