Skip to content
This repository was archived by the owner on Jul 14, 2025. It is now read-only.

Commit f76c30d

Browse files
authored
DEV: Added compatibility with the Glimmer Post Menu (#599)
1 parent 7dd33d2 commit f76c30d

File tree

4 files changed

+511
-48
lines changed

4 files changed

+511
-48
lines changed
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
import Component from "@glimmer/component";
2+
import { action } from "@ember/object";
3+
import { inject as service } from "@ember/service";
4+
import DButton from "discourse/components/d-button";
5+
6+
export default class AssignButton extends Component {
7+
static shouldRender(args) {
8+
return !args.post.firstPost;
9+
}
10+
11+
static hidden(args) {
12+
return args.post.assigned_to_user?.id !== args.state.currentUser.id;
13+
}
14+
15+
@service taskActions;
16+
17+
get icon() {
18+
return this.isAssigned ? "user-times" : "user-plus";
19+
}
20+
21+
get isAssigned() {
22+
return this.args.post.assigned_to_user || this.args.post.assigned_to_group;
23+
}
24+
25+
get title() {
26+
return this.isAssigned
27+
? "discourse_assign.unassign_post.title"
28+
: "discourse_assign.assign_post.title";
29+
}
30+
31+
@action
32+
acceptAnswer() {
33+
if (this.isAssigned) {
34+
unassignPost(this.args.post, this.taskActions);
35+
} else {
36+
assignPost(this.args.post, this.taskActions);
37+
}
38+
}
39+
40+
<template>
41+
<DButton
42+
class={{if
43+
this.isAssigned
44+
"post-action-menu__unassign-post unassign-post"
45+
"post-action-menu__assign-post assign-post"
46+
}}
47+
...attributes
48+
@action={{this.acceptAnswer}}
49+
@icon={{this.icon}}
50+
@title={{this.title}}
51+
/>
52+
</template>
53+
}
54+
55+
// TODO (glimmer-post-menu): Remove these exported functions and move the code into the button action after the widget code is removed
56+
export function assignPost(post, taskActions) {
57+
taskActions.showAssignModal(post, {
58+
isAssigned: false,
59+
targetType: "Post",
60+
});
61+
}
62+
63+
export async function unassignPost(post, taskActions) {
64+
await taskActions.unassign(post.id, "Post");
65+
delete post.topic.indirectly_assigned_to[post.id];
66+
}

assets/javascripts/discourse/initializers/extend-for-assigns.js

Lines changed: 81 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,15 @@ import { registerTopicFooterDropdown } from "discourse/lib/register-topic-footer
1010
import { escapeExpression } from "discourse/lib/utilities";
1111
import RawHtml from "discourse/widgets/raw-html";
1212
import RenderGlimmer from "discourse/widgets/render-glimmer";
13+
import { withSilencedDeprecations } from "discourse-common/lib/deprecated";
1314
import getURL from "discourse-common/lib/get-url";
1415
import { iconHTML, iconNode } from "discourse-common/lib/icon-library";
1516
import discourseComputed from "discourse-common/utils/decorators";
1617
import I18n from "I18n";
18+
import AssignButton, {
19+
assignPost,
20+
unassignPost,
21+
} from "../components/assign-button";
1722
import BulkActionsAssignUser from "../components/bulk-actions/bulk-assign-user";
1823
import EditTopicAssignments from "../components/modal/edit-topic-assignments";
1924
import TopicLevelAssignMenu from "../components/topic-level-assign-menu";
@@ -314,47 +319,9 @@ function initialize(api) {
314319
},
315320
before: "top",
316321
});
317-
if (api.getCurrentUser()?.can_assign) {
318-
api.addPostMenuButton("assign", (post) => {
319-
if (post.firstPost) {
320-
return;
321-
}
322-
if (post.assigned_to_user || post.assigned_to_group) {
323-
return {
324-
action: "unassignPost",
325-
icon: "user-times",
326-
className: "unassign-post",
327-
title: "discourse_assign.unassign_post.title",
328-
position:
329-
post.assigned_to_user?.id === api.getCurrentUser().id
330-
? "first"
331-
: "second-last-hidden",
332-
};
333-
} else {
334-
return {
335-
action: "assignPost",
336-
icon: "user-plus",
337-
className: "assign-post",
338-
title: "discourse_assign.assign_post.title",
339-
position: "second-last-hidden",
340-
};
341-
}
342-
});
343322

344-
api.attachWidgetAction("post", "assignPost", function () {
345-
const taskActions = getOwner(this).lookup("service:task-actions");
346-
taskActions.showAssignModal(this.model, {
347-
isAssigned: false,
348-
targetType: "Post",
349-
});
350-
});
351-
352-
api.attachWidgetAction("post", "unassignPost", function () {
353-
const taskActions = getOwner(this).lookup("service:task-actions");
354-
taskActions.unassign(this.model.id, "Post").then(() => {
355-
delete this.model.topic.indirectly_assigned_to[this.model.id];
356-
});
357-
});
323+
if (api.getCurrentUser()?.can_assign) {
324+
customizePostMenu(api);
358325
}
359326
}
360327

@@ -528,7 +495,9 @@ function initialize(api) {
528495
return new RenderGlimmer(
529496
this,
530497
"p.assigned-to",
531-
hbs`<AssignedToPost @assignedToUser={{@data.assignedToUser}} @assignedToGroup={{@data.assignedToGroup}} @href={{@data.href}} @post={{@data.post}} />`,
498+
hbs`
499+
<AssignedToPost @assignedToUser={{@data.assignedToUser}} @assignedToGroup={{@data.assignedToGroup}}
500+
@href={{@data.href}} @post={{@data.post}} />`,
532501
{
533502
assignedToUser: attrs.post.assigned_to_user,
534503
assignedToGroup: attrs.post.assigned_to_group,
@@ -755,6 +724,76 @@ function initialize(api) {
755724
api.addKeyboardShortcut("g a", "", { path: "/my/activity/assigned" });
756725
}
757726

727+
function customizePostMenu(api) {
728+
const transformerRegistered = api.registerValueTransformer(
729+
"post-menu-buttons",
730+
({
731+
value: dag,
732+
context: {
733+
post,
734+
state,
735+
firstButtonKey,
736+
lastHiddenButtonKey,
737+
secondLastHiddenButtonKey,
738+
},
739+
}) => {
740+
dag.add(
741+
"assign",
742+
AssignButton,
743+
post.assigned_to_user?.id === state.currentUser.id
744+
? {
745+
before: firstButtonKey,
746+
}
747+
: {
748+
before: lastHiddenButtonKey,
749+
after: secondLastHiddenButtonKey,
750+
}
751+
);
752+
}
753+
);
754+
755+
const silencedKey =
756+
transformerRegistered && "discourse.post-menu-widget-overrides";
757+
758+
withSilencedDeprecations(silencedKey, () => customizeWidgetPostMenu(api));
759+
}
760+
761+
function customizeWidgetPostMenu(api) {
762+
api.addPostMenuButton("assign", (post) => {
763+
if (post.firstPost) {
764+
return;
765+
}
766+
if (post.assigned_to_user || post.assigned_to_group) {
767+
return {
768+
action: "unassignPost",
769+
icon: "user-times",
770+
className: "unassign-post",
771+
title: "discourse_assign.unassign_post.title",
772+
position:
773+
post.assigned_to_user?.id === api.getCurrentUser().id
774+
? "first"
775+
: "second-last-hidden",
776+
};
777+
} else {
778+
return {
779+
action: "assignPost",
780+
icon: "user-plus",
781+
className: "assign-post",
782+
title: "discourse_assign.assign_post.title",
783+
position: "second-last-hidden",
784+
};
785+
}
786+
});
787+
788+
api.attachWidgetAction("post", "assignPost", function () {
789+
assignPost(this.model, getOwner(this).lookup("service:task-actions"));
790+
});
791+
792+
api.attachWidgetAction("post", "unassignPost", function () {
793+
unassignPost(this.model, getOwner(this).lookup("service:task-actions"));
794+
});
795+
}
796+
758797
const REGEXP_USERNAME_PREFIX = /^(assigned:)/gi;
759798

760799
export default {
@@ -794,7 +833,7 @@ export default {
794833
});
795834
}
796835

797-
withPluginApi("0.13.0", (api) => {
836+
withPluginApi("1.34.0", (api) => {
798837
extendTopicModel(api, PLUGIN_ID);
799838
initialize(api);
800839
registerTopicFooterButtons(api);

test/javascripts/acceptance/assign-enabled-test.js

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import { cloneJSON } from "discourse-common/lib/object";
1515
acceptance("Discourse Assign | Assign mobile", function (needs) {
1616
needs.user();
1717
needs.mobileView();
18-
needs.settings({ assign_enabled: true });
18+
needs.settings({ glimmer_post_menu_mode: "enabled", assign_enabled: true });
1919

2020
needs.pretender((server, helper) => {
2121
server.get("/assign/suggestions", () => {
@@ -52,7 +52,7 @@ acceptance("Discourse Assign | Assign desktop", function (needs) {
5252
needs.user({
5353
can_assign: true,
5454
});
55-
needs.settings({ assign_enabled: true });
55+
needs.settings({ glimmer_post_menu_mode: "enabled", assign_enabled: true });
5656

5757
needs.pretender((server, helper) => {
5858
server.get("/assign/suggestions", () => {
@@ -77,15 +77,15 @@ acceptance("Discourse Assign | Assign desktop", function (needs) {
7777
await visit("/t/internationalization-localization/280");
7878

7979
assert
80-
.dom("#post_2 .extra-buttons .d-icon-user-plus")
80+
.dom("#post_2 .post-action-menu__assign-post")
8181
.doesNotExist("assign to post button is hidden");
8282

8383
await click("#post_2 button.show-more-actions");
8484
assert
85-
.dom("#post_2 .extra-buttons .d-icon-user-plus")
85+
.dom("#post_2 .post-action-menu__assign-post")
8686
.exists("assign to post button exists");
8787

88-
await click("#post_2 .extra-buttons .d-icon-user-plus");
88+
await click("#post_2 .post-action-menu__assign-post");
8989
assert.dom(".assign.d-modal").exists("assign modal opens");
9090

9191
const menu = selectKit(".assign.d-modal .user-chooser");
@@ -126,6 +126,7 @@ acceptance("Discourse Assign | Assign Status enabled", function (needs) {
126126
can_assign: true,
127127
});
128128
needs.settings({
129+
glimmer_post_menu_mode: "enabled",
129130
assign_enabled: true,
130131
enable_assign_status: true,
131132
assign_statuses: "New|In Progress|Done",
@@ -187,7 +188,11 @@ acceptance("Discourse Assign | Assign Status disabled", function (needs) {
187188
needs.user({
188189
can_assign: true,
189190
});
190-
needs.settings({ assign_enabled: true, enable_assign_status: false });
191+
needs.settings({
192+
glimmer_post_menu_mode: "enabled",
193+
assign_enabled: true,
194+
enable_assign_status: false,
195+
});
191196

192197
needs.pretender((server, helper) => {
193198
server.get("/assign/suggestions", () => {
@@ -245,6 +250,7 @@ const remindersFrequency = [
245250
acceptance("Discourse Assign | User preferences", function (needs) {
246251
needs.user({ can_assign: true, reminders_frequency: remindersFrequency });
247252
needs.settings({
253+
glimmer_post_menu_mode: "enabled",
248254
assign_enabled: true,
249255
remind_assigns_frequency: 43200,
250256
});
@@ -291,6 +297,7 @@ acceptance(
291297
function (needs) {
292298
needs.user({ can_assign: true, reminders_frequency: remindersFrequency });
293299
needs.settings({
300+
glimmer_post_menu_mode: "enabled",
294301
assign_enabled: true,
295302
remind_assigns_frequency: 43200,
296303
});

0 commit comments

Comments
 (0)