DEV: Modernise assignment topic-list implementation (#510)

- Reuse core `<BasicTopicList` instead of reimplementing
- Use raw plugin outlet to add assign controls to topic-list-item (requires https://github.com/discourse/discourse/pull/23592)
- Remove use of `.render()` in route
This commit is contained in:
David Taylor 2023-09-28 15:07:15 +01:00 committed by GitHub
parent e9c7cb5c3f
commit 89807545a4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
22 changed files with 852 additions and 496 deletions

View File

@ -1 +1,17 @@
{}
{
"plugins": ["prettier-plugin-ember-template-tag"],
"overrides": [
{
"files": "*.gjs",
"options": {
"parser": "ember-template-tag"
}
},
{
"files": "*.gts",
"options": {
"parser": "ember-template-tag"
}
}
]
}

View File

@ -51,7 +51,6 @@
<Textarea
id="assign-modal-note"
@value={{@model.note}}
{{! template-lint-disable no-down-event-binding }}
{{on "keydown" this.handleTextAreaKeydown}}
/>
</div>

View File

@ -9,8 +9,8 @@ export default class AssignUserForm extends Component {
@service capabilities;
@tracked assigneeError = false;
@tracked assigneeName =
this.args.model.username || this.args.model.group_name;
@tracked
assigneeName = this.args.model.username || this.args.model.group_name;
constructor() {
super(...arguments);

View File

@ -0,0 +1,45 @@
import Component from "@glimmer/component";
import AssignActionsDropdown from "./assign-actions-dropdown";
import { inject as service } from "@ember/service";
import { action } from "@ember/object";
export default class AssignedTopicListColumn_Test extends Component {
<template>
<td class="topic-list-data">
{{#if @topic.assigned_to_user}}
<AssignActionsDropdown
@topic={{@topic}}
@assignee={{@topic.assigned_to_user.username}}
@unassign={{this.unassign}}
@reassign={{this.reassign}}
/>
{{else if @topic.assigned_to_group}}
<AssignActionsDropdown
@topic={{@topic}}
@assignee={{@topic.assigned_to_group.name}}
@group={{true}}
@unassign={{this.unassign}}
@reassign={{this.reassign}}
/>
{{else}}
<AssignActionsDropdown @topic={{@topic}} @unassign={{this.unassign}} />
{{/if}}
</td>
</template>
@service taskActions;
@service router;
@action
async unassign(targetId, targetType = "Topic") {
await this.taskActions.unassign(targetId, targetType);
this.router.refresh();
}
@action
reassign(topic) {
this.taskActions.showAssignModal(topic, {
onSuccess: () => this.router.refresh(),
});
}
}

View File

@ -1,86 +0,0 @@
{{!
The `~` syntax strip spaces between the elements, making it produce
`<a class=topic-post-badges>Some text</a><span class=topic-post-badges>`,
with no space between them.
This causes the topic-post-badge to be considered the same word as "text"
at the end of the link, preventing it from line wrapping onto its own line.
}}
{{#if this.bulkSelectEnabled}}
<td class="bulk-select topic-list-data">
<input type="checkbox" class="bulk-select" />
</td>
{{/if}}
<td class="main-link clearfix topic-list-data" colspan="1">
<span class="link-top-line">
{{~raw "topic-status" topic=this.topic}}
{{~#if this.isPrivateMessage}}
{{~d-icon "envelope" class="private-message-icon"}}
{{~/if}}
{{~topic-link this.topic class="raw-link raw-topic-link"}}
{{~#if this.topic.featured_link}}
{{~topic-featured-link this.topic}}
{{~/if}}
{{~#if this.showTopicPostBadges}}
{{~raw
"topic-post-badges"
unread=this.topic.unread
unseen=this.topic.unseen
url=this.topic.lastUnreadUrl
newDotText=this.newDotText
}}
{{~/if}}
</span>
<div class="link-bottom-line">
{{#if (or (not this.hideCategory) (not this.topic.isPinnedUncategorized))}}
{{category-link this.topic.category}}
{{/if}}
{{discourse-tags this.topic mode="list" tagsForUser=this.tagsForUser}}
{{raw
"list/action-list"
topic=this.topic
postNumbers=this.topic.liked_post_numbers
className="likes"
icon="heart"
}}
</div>
{{#if this.expandPinned}}
{{raw "list/topic-excerpt" topic=this.topic}}
{{/if}}
</td>
{{#if this.showPosters}}
{{raw "list/posters-column" posters=this.topic.featuredUsers}}
{{/if}}
{{raw "list/posts-count-column" topic=this.topic}}
<td class="num views {{this.topic.viewsHeat}} topic-list-data">{{number
this.topic.views
numberKey="views_long"
}}</td>
{{raw
"list/activity-column"
topic=this.topic
class="num topic-list-data"
tagName="td"
}}
<td class="topic-list-data">
{{#if this.topic.assigned_to_user}}
<AssignActionsDropdown
@topic={{this.topic}}
@assignee={{this.topic.assigned_to_user.username}}
@unassign={{this.unassign}}
@reassign={{this.reassign}}
/>
{{else if this.topic.assigned_to_group}}
<AssignActionsDropdown
@topic={{this.topic}}
@assignee={{this.topic.assigned_to_group.name}}
@group={{true}}
@unassign={{this.unassign}}
@reassign={{this.reassign}}
/>
{{else}}
<AssignActionsDropdown @topic={{this.topic}} @unassign={{this.unassign}} />
{{/if}}
</td>

View File

@ -1,8 +0,0 @@
import TopicListItem from "discourse/components/topic-list-item";
import { equal } from "@ember/object/computed";
export default class AssignedTopicListItem extends TopicListItem {
classNames = ["assigned-topic-list-item"];
@equal("topic.archetype", "private_message") isPrivateMessage;
}

View File

@ -1,46 +0,0 @@
{{#unless this.skipHeader}}
<thead class="topic-list-header assigned-topic-list-header">
{{raw
"topic-list-header"
canBulkSelect=this.canBulkSelect
canDoBulkActions=this.canDoBulkActions
toggleInTitle=this.toggleInTitle
hideCategory=this.hideCategory
showPosters=true
showLikes=this.showLikes
showOpLikes=this.showOpLikes
order=this.order
ascending=this.ascending
sortable=this.sortable
listTitle=this.listTitle
bulkSelectEnabled=this.bulkSelectEnabled
}}
</thead>
{{/unless}}
<tbody class="topic-list-body assigned-topic-list-body">
{{#each this.filteredTopics as |topic|}}
<AssignedTopicListItem
@topic={{topic}}
@bulkSelectEnabled={{this.bulkSelectEnabled}}
@showTopicPostBadges={{this.showTopicPostBadges}}
@hideCategory={{this.hideCategory}}
@showPosters={{true}}
@showLikes={{this.showLikes}}
@showOpLikes={{this.showOpLikes}}
@expandGloballyPinned={{this.expandGloballyPinned}}
@expandAllPinned={{this.expandAllPinned}}
@lastVisitedTopic={{this.lastVisitedTopic}}
@selected={{this.selected}}
@tagsForUser={{this.tagsForUser}}
@unassign={{this.unassign}}
@reassign={{this.reassign}}
/>
{{raw
"list/visited-line"
lastVisitedTopic=this.lastVisitedTopic
topic=topic
}}
{{/each}}
</tbody>

View File

@ -1,3 +0,0 @@
import TopicList from "discourse/components/topic-list";
export default class AssignedTopicList extends TopicList {}

View File

@ -1,40 +0,0 @@
<ConditionalLoadingSpinner @condition={{this.loading}}>
{{#if this.hasIncoming}}
<div class="show-mores">
<a href class="alert alert-info clickable" {{action this.showInserted}}>
<CountI18n
@key="topic_count_"
@suffix="latest"
@count={{this.incomingCount}}
/>
</a>
</div>
{{/if}}
{{#if this.topics}}
<AssignedTopicList
@showPosters={{this.showPosters}}
@hideCategory={{this.hideCategory}}
@topics={{this.topics}}
@expandExcerpts={{this.expandExcerpts}}
@bulkSelectEnabled={{this.bulkSelectEnabled}}
@canBulkSelect={{this.canBulkSelect}}
@bulkSelectAction={{this.bulkSelectAction}}
@selected={{this.selected}}
@skipHeader={{this.skipHeader}}
@tagsForUser={{this.tagsForUser}}
@changeSort={{this.changeSort}}
@toggleBulkSelect={{this.toggleBulkSelect}}
@unassign={{this.unassign}}
@reassign={{this.reassign}}
@onScroll={{this.onScroll}}
@scrollOnLoad={{this.scrollOnLoad}}
/>
{{else}}
{{#unless this.loadingMore}}
<div class="alert alert-info">
{{i18n "choose_topic.none_found"}}
</div>
{{/unless}}
{{/if}}
</ConditionalLoadingSpinner>

View File

@ -1,3 +0,0 @@
import BasicTopicList from "discourse/components/basic-topic-list";
export default class BasicAssignedTopicList extends BasicTopicList {}

View File

@ -0,0 +1 @@
{{raw "assign-topic-buttons" topic=context.topic}}

View File

@ -8,6 +8,7 @@ import { action } from "@ember/object";
export default class GroupAssignedShow extends UserTopicsList {
@service taskActions;
@service router;
@controller user;
queryParams = ["order", "ascending", "search"];
@ -45,13 +46,13 @@ export default class GroupAssignedShow extends UserTopicsList {
@action
async unassign(targetId, targetType = "Topic") {
await this.taskActions.unassign(targetId, targetType);
this.send("changeAssigned");
this.router.refresh();
}
@action
reassign(topic) {
this.taskActions.showAssignModal(topic, {
onSuccess: () => this.send("changeAssigned"),
onSuccess: () => this.router.refresh(),
});
}

View File

@ -56,19 +56,6 @@ export default class UserActivityAssigned extends UserTopicsList {
});
}
@action
async unassign(targetId, targetType = "Topic") {
await this.taskActions.unassign(targetId, targetType);
this.send("changeAssigned");
}
@action
reassign(topic) {
this.taskActions.showAssignModal(topic, {
onSuccess: () => this.send("changeAssigned"),
});
}
@action
changeSort(sortBy) {
if (sortBy === this.order) {

View File

@ -0,0 +1 @@
{{{view.html}}}

View File

@ -0,0 +1,21 @@
import EmberObject from "@ember/object";
import rawRenderGlimmer from "discourse/lib/raw-render-glimmer";
import AssignedTopicListColumn from "../components/assigned-topic-list-column";
import { inject as service } from "@ember/service";
const ASSIGN_LIST_ROUTES = ["userActivity.assigned", "group.assigned.show"];
export default class extends EmberObject {
@service router;
get html() {
if (ASSIGN_LIST_ROUTES.includes(this.router.currentRouteName)) {
return rawRenderGlimmer(
this,
"div.assign-topic-buttons",
<template><AssignedTopicListColumn @topic={{@data.topic}} /></template>,
{ topic: this.topic }
);
}
}
}

View File

@ -2,12 +2,6 @@ import DiscourseRoute from "discourse/routes/discourse";
import { findOrResetCachedTopicList } from "discourse/lib/cached-topic-list";
export default class GroupAssignedShow extends DiscourseRoute {
beforeModel(transition) {
if (transition.from?.localName === "show") {
this.session.set("topicListScrollPosition", 1);
}
}
model(params) {
let filter;
if (["everyone", this.modelFor("group").name].includes(params.filter)) {
@ -36,8 +30,4 @@ export default class GroupAssignedShow extends DiscourseRoute {
search: this.currentModel.params.search,
});
}
renderTemplate() {
this.render("group-topics-list");
}
}

View File

@ -1,6 +1,5 @@
import DiscourseRoute from "discourse/routes/discourse";
import { ajax } from "discourse/lib/ajax";
import { action } from "@ember/object";
export default class GroupAssigned extends DiscourseRoute {
model() {
@ -28,9 +27,4 @@ export default class GroupAssigned extends DiscourseRoute {
this.transitionTo("group.assigned.show", "everyone");
}
}
@action
changeAssigned() {
this.refresh();
}
}

View File

@ -1,7 +1,6 @@
import I18n from "I18n";
import UserTopicListRoute from "discourse/routes/user-topic-list";
import cookie from "discourse/lib/cookie";
import { action } from "@ember/object";
export default class UserActivityAssigned extends UserTopicListRoute {
templateName = "user-activity-assigned";
@ -34,9 +33,4 @@ export default class UserActivityAssigned extends UserTopicListRoute {
titleToken() {
return I18n.t("discourse_assign.assigned");
}
@action
changeAssigned() {
this.refresh();
}
}

View File

@ -16,7 +16,7 @@
@selector=".paginated-topics-list .topic-list tr"
@action={{action "loadMore"}}
>
<BasicAssignedTopicList
<BasicTopicList
@topicList={{this.model}}
@hideCategory={{this.hideCategory}}
@showPosters={{this.showPosters}}

View File

@ -22,7 +22,7 @@
@selector=".paginated-topics-list .topic-list tr"
@action={{action "loadMore"}}
>
<BasicAssignedTopicList
<BasicTopicList
@topicList={{this.model}}
@hideCategory={{this.hideCategory}}
@showPosters={{true}}

View File

@ -5,6 +5,7 @@
"author": "Discourse",
"license": "MIT",
"devDependencies": {
"eslint-config-discourse": "^3.4.0"
"eslint-config-discourse": "^4.0.0",
"prettier-plugin-ember-template-tag": "^0.3.2"
}
}

1024
yarn.lock

File diff suppressed because it is too large Load Diff