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
|
<Textarea
|
||||||
id="assign-modal-note"
|
id="assign-modal-note"
|
||||||
@value={{@model.note}}
|
@value={{@model.note}}
|
||||||
{{! template-lint-disable no-down-event-binding }}
|
|
||||||
{{on "keydown" this.handleTextAreaKeydown}}
|
{{on "keydown" this.handleTextAreaKeydown}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
|
@ -9,8 +9,8 @@ export default class AssignUserForm extends Component {
|
||||||
@service capabilities;
|
@service capabilities;
|
||||||
|
|
||||||
@tracked assigneeError = false;
|
@tracked assigneeError = false;
|
||||||
@tracked assigneeName =
|
@tracked
|
||||||
this.args.model.username || this.args.model.group_name;
|
assigneeName = this.args.model.username || this.args.model.group_name;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super(...arguments);
|
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 {
|
export default class GroupAssignedShow extends UserTopicsList {
|
||||||
@service taskActions;
|
@service taskActions;
|
||||||
|
@service router;
|
||||||
@controller user;
|
@controller user;
|
||||||
|
|
||||||
queryParams = ["order", "ascending", "search"];
|
queryParams = ["order", "ascending", "search"];
|
||||||
|
@ -45,13 +46,13 @@ export default class GroupAssignedShow extends UserTopicsList {
|
||||||
@action
|
@action
|
||||||
async unassign(targetId, targetType = "Topic") {
|
async unassign(targetId, targetType = "Topic") {
|
||||||
await this.taskActions.unassign(targetId, targetType);
|
await this.taskActions.unassign(targetId, targetType);
|
||||||
this.send("changeAssigned");
|
this.router.refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
reassign(topic) {
|
reassign(topic) {
|
||||||
this.taskActions.showAssignModal(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
|
@action
|
||||||
changeSort(sortBy) {
|
changeSort(sortBy) {
|
||||||
if (sortBy === this.order) {
|
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";
|
import { findOrResetCachedTopicList } from "discourse/lib/cached-topic-list";
|
||||||
|
|
||||||
export default class GroupAssignedShow extends DiscourseRoute {
|
export default class GroupAssignedShow extends DiscourseRoute {
|
||||||
beforeModel(transition) {
|
|
||||||
if (transition.from?.localName === "show") {
|
|
||||||
this.session.set("topicListScrollPosition", 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
model(params) {
|
model(params) {
|
||||||
let filter;
|
let filter;
|
||||||
if (["everyone", this.modelFor("group").name].includes(params.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,
|
search: this.currentModel.params.search,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
renderTemplate() {
|
|
||||||
this.render("group-topics-list");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
import DiscourseRoute from "discourse/routes/discourse";
|
import DiscourseRoute from "discourse/routes/discourse";
|
||||||
import { ajax } from "discourse/lib/ajax";
|
import { ajax } from "discourse/lib/ajax";
|
||||||
import { action } from "@ember/object";
|
|
||||||
|
|
||||||
export default class GroupAssigned extends DiscourseRoute {
|
export default class GroupAssigned extends DiscourseRoute {
|
||||||
model() {
|
model() {
|
||||||
|
@ -28,9 +27,4 @@ export default class GroupAssigned extends DiscourseRoute {
|
||||||
this.transitionTo("group.assigned.show", "everyone");
|
this.transitionTo("group.assigned.show", "everyone");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
|
||||||
changeAssigned() {
|
|
||||||
this.refresh();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
import I18n from "I18n";
|
import I18n from "I18n";
|
||||||
import UserTopicListRoute from "discourse/routes/user-topic-list";
|
import UserTopicListRoute from "discourse/routes/user-topic-list";
|
||||||
import cookie from "discourse/lib/cookie";
|
import cookie from "discourse/lib/cookie";
|
||||||
import { action } from "@ember/object";
|
|
||||||
|
|
||||||
export default class UserActivityAssigned extends UserTopicListRoute {
|
export default class UserActivityAssigned extends UserTopicListRoute {
|
||||||
templateName = "user-activity-assigned";
|
templateName = "user-activity-assigned";
|
||||||
|
@ -34,9 +33,4 @@ export default class UserActivityAssigned extends UserTopicListRoute {
|
||||||
titleToken() {
|
titleToken() {
|
||||||
return I18n.t("discourse_assign.assigned");
|
return I18n.t("discourse_assign.assigned");
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
|
||||||
changeAssigned() {
|
|
||||||
this.refresh();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
@selector=".paginated-topics-list .topic-list tr"
|
@selector=".paginated-topics-list .topic-list tr"
|
||||||
@action={{action "loadMore"}}
|
@action={{action "loadMore"}}
|
||||||
>
|
>
|
||||||
<BasicAssignedTopicList
|
<BasicTopicList
|
||||||
@topicList={{this.model}}
|
@topicList={{this.model}}
|
||||||
@hideCategory={{this.hideCategory}}
|
@hideCategory={{this.hideCategory}}
|
||||||
@showPosters={{this.showPosters}}
|
@showPosters={{this.showPosters}}
|
|
@ -22,7 +22,7 @@
|
||||||
@selector=".paginated-topics-list .topic-list tr"
|
@selector=".paginated-topics-list .topic-list tr"
|
||||||
@action={{action "loadMore"}}
|
@action={{action "loadMore"}}
|
||||||
>
|
>
|
||||||
<BasicAssignedTopicList
|
<BasicTopicList
|
||||||
@topicList={{this.model}}
|
@topicList={{this.model}}
|
||||||
@hideCategory={{this.hideCategory}}
|
@hideCategory={{this.hideCategory}}
|
||||||
@showPosters={{true}}
|
@showPosters={{true}}
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
"author": "Discourse",
|
"author": "Discourse",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"devDependencies": {
|
"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