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:
parent
e9c7cb5c3f
commit
89807545a4
18
.prettierrc
18
.prettierrc
|
@ -1 +1,17 @@
|
|||
{}
|
||||
{
|
||||
"plugins": ["prettier-plugin-ember-template-tag"],
|
||||
"overrides": [
|
||||
{
|
||||
"files": "*.gjs",
|
||||
"options": {
|
||||
"parser": "ember-template-tag"
|
||||
}
|
||||
},
|
||||
{
|
||||
"files": "*.gts",
|
||||
"options": {
|
||||
"parser": "ember-template-tag"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
@ -51,7 +51,6 @@
|
|||
<Textarea
|
||||
id="assign-modal-note"
|
||||
@value={{@model.note}}
|
||||
{{! template-lint-disable no-down-event-binding }}
|
||||
{{on "keydown" this.handleTextAreaKeydown}}
|
||||
/>
|
||||
</div>
|
|
@ -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);
|
||||
|
|
|
@ -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(),
|
||||
});
|
||||
}
|
||||
}
|
|
@ -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>
|
|
@ -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;
|
||||
}
|
|
@ -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>
|
|
@ -1,3 +0,0 @@
|
|||
import TopicList from "discourse/components/topic-list";
|
||||
|
||||
export default class AssignedTopicList extends TopicList {}
|
|
@ -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>
|
|
@ -1,3 +0,0 @@
|
|||
import BasicTopicList from "discourse/components/basic-topic-list";
|
||||
|
||||
export default class BasicAssignedTopicList extends BasicTopicList {}
|
|
@ -0,0 +1 @@
|
|||
{{raw "assign-topic-buttons" topic=context.topic}}
|
|
@ -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(),
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
{{{view.html}}}
|
|
@ -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 }
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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}}
|
|
@ -22,7 +22,7 @@
|
|||
@selector=".paginated-topics-list .topic-list tr"
|
||||
@action={{action "loadMore"}}
|
||||
>
|
||||
<BasicAssignedTopicList
|
||||
<BasicTopicList
|
||||
@topicList={{this.model}}
|
||||
@hideCategory={{this.hideCategory}}
|
||||
@showPosters={{true}}
|
||||
|
|
|
@ -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"
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue