diff --git a/assets/javascripts/discourse/components/assign-user-form.gjs b/assets/javascripts/discourse/components/assign-user-form.gjs
new file mode 100644
index 0000000..f8ff6d7
--- /dev/null
+++ b/assets/javascripts/discourse/components/assign-user-form.gjs
@@ -0,0 +1,36 @@
+import Component from "@glimmer/component";
+import { tracked } from "@glimmer/tracking";
+import { action } from "@ember/object";
+import Assignment from "./assignment";
+
+export default class AssignUserForm extends Component {
+ @tracked showValidationErrors = false;
+
+ constructor() {
+ super(...arguments);
+
+ this.args.formApi.submit = this.assign;
+ }
+
+ get assigneeIsEmpty() {
+ return !this.args.model.username && !this.args.model.group_name;
+ }
+
+ @action
+ async assign() {
+ if (this.assigneeIsEmpty) {
+ this.showValidationErrors = true;
+ return;
+ }
+
+ await this.args.onSubmit();
+ }
+
+
+
+
+}
diff --git a/assets/javascripts/discourse/components/assign-user-form.hbs b/assets/javascripts/discourse/components/assign-user-form.hbs
deleted file mode 100644
index 9b3bc37..0000000
--- a/assets/javascripts/discourse/components/assign-user-form.hbs
+++ /dev/null
@@ -1,56 +0,0 @@
-
-
-
-
- {{#if this.assigneeError}}
-
- {{d-icon "exclamation-triangle"}}
- {{i18n "discourse_assign.assign_modal.choose_assignee"}}
-
- {{/if}}
-
-
-{{#if this.siteSettings.enable_assign_status}}
-
-
-
-
-{{/if}}
-
-
-
-
-
-
\ No newline at end of file
diff --git a/assets/javascripts/discourse/components/assign-user-form.js b/assets/javascripts/discourse/components/assign-user-form.js
deleted file mode 100644
index 0501018..0000000
--- a/assets/javascripts/discourse/components/assign-user-form.js
+++ /dev/null
@@ -1,63 +0,0 @@
-import Component from "@glimmer/component";
-import { tracked } from "@glimmer/tracking";
-import { action } from "@ember/object";
-import { inject as service } from "@ember/service";
-
-export default class AssignUserForm extends Component {
- @service taskActions;
- @service siteSettings;
- @service capabilities;
-
- @tracked assigneeError = false;
- @tracked
- assigneeName = this.args.model.username || this.args.model.group_name;
-
- constructor() {
- super(...arguments);
-
- this.args.formApi.submit = this.assign;
- }
-
- get availableStatuses() {
- return this.siteSettings.assign_statuses
- .split("|")
- .map((status) => ({ id: status, name: status }));
- }
-
- get status() {
- return (
- this.args.model.status || this.siteSettings.assign_statuses.split("|")[0]
- );
- }
-
- @action
- handleTextAreaKeydown(event) {
- if ((event.ctrlKey || event.metaKey) && event.key === "Enter") {
- this.assign();
- }
- }
-
- @action
- async assign() {
- if (!this.assigneeName) {
- this.assigneeError = true;
- return;
- }
-
- await this.args.onSubmit();
- }
-
- @action
- assignUsername([name]) {
- this.assigneeName = name;
- this.assigneeError = false;
-
- if (this.taskActions.allowedGroupsForAssignment.includes(name)) {
- this.args.model.username = null;
- this.args.model.group_name = name;
- } else {
- this.args.model.username = name;
- this.args.model.group_name = null;
- }
- }
-}
diff --git a/assets/javascripts/discourse/components/assignment.gjs b/assets/javascripts/discourse/components/assignment.gjs
new file mode 100644
index 0000000..3203285
--- /dev/null
+++ b/assets/javascripts/discourse/components/assignment.gjs
@@ -0,0 +1,134 @@
+import Component from "@glimmer/component";
+import { hash } from "@ember/helper";
+import { TextArea } from "@ember/legacy-built-in-components";
+import { on } from "@ember/modifier";
+import { action } from "@ember/object";
+import { inject as service } from "@ember/service";
+import icon from "discourse-common/helpers/d-icon";
+import i18n from "discourse-common/helpers/i18n";
+import ComboBox from "select-kit/components/combo-box";
+import not from "truth-helpers/helpers/not";
+import AssigneeChooser from "./assignee-chooser";
+
+export default class Assignment extends Component {
+ @service siteSettings;
+ @service taskActions;
+
+ get assignee() {
+ return this.args.assignment.username || this.args.assignment.group_name;
+ }
+
+ get status() {
+ return this.args.assignment.status || this.assignStatuses[0];
+ }
+
+ get assignStatuses() {
+ return this.siteSettings.assign_statuses.split("|").filter(Boolean);
+ }
+
+ get assignStatusOptions() {
+ return this.assignStatuses.map((status) => ({ id: status, name: status }));
+ }
+
+ get assigneeIsEmpty() {
+ return !this.args.assignment.username && !this.args.assignment.group_name;
+ }
+
+ get showAssigneeIeEmptyError() {
+ return this.assigneeIsEmpty && this.args.showValidationErrors;
+ }
+
+ @action
+ handleTextAreaKeydown(event) {
+ if ((event.ctrlKey || event.metaKey) && event.key === "Enter") {
+ this.args.onSubmit();
+ }
+ }
+
+ @action
+ markAsEdited() {
+ this.args.assignment.isEdited = true;
+ }
+
+ @action
+ setAssignee([newAssignee]) {
+ if (this.taskActions.allowedGroupsForAssignment.includes(newAssignee)) {
+ this.args.assignment.username = null;
+ this.args.assignment.group_name = newAssignee;
+ } else {
+ this.args.assignment.username = newAssignee;
+ this.args.assignment.group_name = null;
+ }
+ this.markAsEdited();
+ }
+
+ @action
+ setStatus(status) {
+ this.args.assignment.status = status;
+ this.markAsEdited();
+ }
+
+
+
+
+
+
+ {{#if this.showAssigneeIeEmptyError}}
+
+ {{icon "exclamation-triangle"}}
+ {{i18n "discourse_assign.assign_modal.choose_assignee"}}
+
+ {{/if}}
+
+
+ {{#if this.siteSettings.enable_assign_status}}
+
+
+
+
+ {{/if}}
+
+
+
+
+
+
+
+}
diff --git a/assets/javascripts/discourse/components/modal/edit-topic-assignments.gjs b/assets/javascripts/discourse/components/modal/edit-topic-assignments.gjs
new file mode 100644
index 0000000..185faa3
--- /dev/null
+++ b/assets/javascripts/discourse/components/modal/edit-topic-assignments.gjs
@@ -0,0 +1,67 @@
+import Component from "@glimmer/component";
+import { tracked } from "@glimmer/tracking";
+import { action } from "@ember/object";
+import { inject as service } from "@ember/service";
+import DButton from "discourse/components/d-button";
+import DModal from "discourse/components/d-modal";
+import DModalCancel from "discourse/components/d-modal-cancel";
+import { popupAjaxError } from "discourse/lib/ajax-error";
+import I18n from "I18n";
+import TopicAssignments from "../topic-assignments";
+
+export default class EditTopicAssignments extends Component {
+ @service taskActions;
+
+ @tracked assignments = this.topic.assignments();
+
+ get title() {
+ if (this.topic.isAssigned() || this.topic.hasAssignedPosts()) {
+ return I18n.t("edit_assignments_modal.title");
+ } else {
+ return I18n.t("discourse_assign.assign_modal.title");
+ }
+ }
+
+ get topic() {
+ return this.args.model.topic;
+ }
+
+ @action
+ async submit() {
+ this.args.closeModal();
+ try {
+ await this.#assign();
+ } catch (error) {
+ popupAjaxError(error);
+ }
+ }
+
+ async #assign() {
+ for (const assignment of this.assignments) {
+ if (assignment.isEdited) {
+ await this.taskActions.putAssignment(assignment);
+ }
+ }
+ }
+
+
+
+ <:body>
+
+
+ <:footer>
+
+
+
+
+
+
+}
diff --git a/assets/javascripts/discourse/components/topic-assignments.gjs b/assets/javascripts/discourse/components/topic-assignments.gjs
new file mode 100644
index 0000000..f4d515f
--- /dev/null
+++ b/assets/javascripts/discourse/components/topic-assignments.gjs
@@ -0,0 +1,48 @@
+import Component from "@glimmer/component";
+import { tracked } from "@glimmer/tracking";
+import { action } from "@ember/object";
+import i18n from "discourse-common/helpers/i18n";
+import I18n from "I18n";
+import ComboBox from "select-kit/components/combo-box";
+import Assignment from "./assignment";
+
+export default class TopicAssignments extends Component {
+ @tracked selectedAssignment = this.args.assignments.find((a) => a.id === 0);
+
+ get assignmentOptions() {
+ return this.args.assignments.map((a) => this.#toComboBoxOption(a));
+ }
+
+ @action
+ selectAssignment(id) {
+ this.selectedAssignment = this.args.assignments.find((a) => a.id === id);
+ }
+
+ #toComboBoxOption(assignment) {
+ const option = { id: assignment.id };
+ if (assignment.targetType === "Topic") {
+ option.name = I18n.t("edit_assignments_modal.topic");
+ } else {
+ option.name = `${I18n.t("edit_assignments_modal.post")} #${
+ assignment.postNumber
+ }`;
+ }
+ return option;
+ }
+
+
+
+
+
+
+
+
+}
diff --git a/assets/javascripts/discourse/components/topic-level-assign-menu.js b/assets/javascripts/discourse/components/topic-level-assign-menu.js
index f3d01b1..7d21ecd 100644
--- a/assets/javascripts/discourse/components/topic-level-assign-menu.js
+++ b/assets/javascripts/discourse/components/topic-level-assign-menu.js
@@ -3,6 +3,7 @@ import { htmlSafe } from "@ember/template";
import { renderAvatar } from "discourse/helpers/user-avatar";
import { iconHTML } from "discourse-common/lib/icon-library";
import I18n from "I18n";
+import EditTopicAssignments from "../components/modal/edit-topic-assignments";
const DEPENDENT_KEYS = [
"topic.assigned_to_user",
@@ -22,6 +23,7 @@ export default {
}
const taskActions = getOwner(this).lookup("service:task-actions");
+ const modal = getOwner(this).lookup("service:modal");
const firstPostId = this.topic.postStream.firstPostId;
switch (id) {
@@ -42,9 +44,10 @@ export default {
break;
}
case "reassign": {
- await taskActions.showAssignModal(this.topic, {
- targetType: "Topic",
- isAssigned: this.topic.isAssigned(),
+ await modal.show(EditTopicAssignments, {
+ model: {
+ topic: this.topic,
+ },
onSuccess: () =>
this.appEvents.trigger("post-stream:refresh", { id: firstPostId }),
});
@@ -64,6 +67,7 @@ export default {
noneItem() {
return topicLevelUnassignButton(this.topic.uniqueAssignees());
},
+
content() {
const content = [];
diff --git a/assets/javascripts/discourse/initializers/extend-for-assigns.js b/assets/javascripts/discourse/initializers/extend-for-assigns.js
index dcde7df..c98db46 100644
--- a/assets/javascripts/discourse/initializers/extend-for-assigns.js
+++ b/assets/javascripts/discourse/initializers/extend-for-assigns.js
@@ -16,7 +16,9 @@ import discourseComputed from "discourse-common/utils/decorators";
import I18n from "I18n";
import BulkAssign from "../components/bulk-actions/assign-user";
import BulkActionsAssignUser from "../components/bulk-actions/bulk-assign-user";
+import EditTopicAssignments from "../components/modal/edit-topic-assignments";
import TopicLevelAssignMenu from "../components/topic-level-assign-menu";
+import { extendTopicModel } from "../models/topic";
const PLUGIN_ID = "discourse-assign";
@@ -38,50 +40,6 @@ function defaultTitle(topic) {
}
}
-function extendTopicModel(api) {
- api.modifyClass("model:topic", {
- pluginId: PLUGIN_ID,
-
- assignees() {
- const result = [];
-
- if (this.assigned_to_user) {
- result.push(this.assigned_to_user);
- }
-
- const postAssignees = this.assignedPosts().map((p) => p.assigned_to);
- result.push(...postAssignees);
- return result;
- },
-
- uniqueAssignees() {
- const map = new Map();
- this.assignees().forEach((user) => map.set(user.username, user));
- return [...map.values()];
- },
-
- assignedPosts() {
- if (!this.indirectly_assigned_to) {
- return [];
- }
-
- return Object.values(this.indirectly_assigned_to);
- },
-
- isAssigned() {
- return this.assigned_to_user || this.assigned_to_group;
- },
-
- isAssignedTo(user) {
- return this.assigned_to_user?.username === user.username;
- },
-
- hasAssignedPosts() {
- return !!this.assignedPosts().length;
- },
- });
-}
-
function registerTopicFooterButtons(api) {
registerTopicFooterDropdown(TopicLevelAssignMenu);
@@ -110,6 +68,7 @@ function registerTopicFooterButtons(api) {
}
const taskActions = getOwner(this).lookup("service:task-actions");
+ const modal = getOwner(this).lookup("service:modal");
if (this.topic.isAssigned()) {
this.set("topic.assigned_to_user", null);
@@ -121,7 +80,10 @@ function registerTopicFooterButtons(api) {
id: this.topic.postStream.firstPostId,
});
} else {
- await taskActions.showAssignModal(this.topic, {
+ await modal.show(EditTopicAssignments, {
+ model: {
+ topic: this.topic,
+ },
onSuccess: () =>
this.appEvents.trigger("post-stream:refresh", {
id: this.topic.postStream.firstPostId,
@@ -723,6 +685,9 @@ function initialize(api) {
}
}
this.appEvents.trigger("header:update-topic", topic);
+ this.appEvents.trigger("post-stream:refresh", {
+ id: topic.postStream.posts[0].id,
+ });
});
},
@@ -833,7 +798,7 @@ export default {
}
withPluginApi("0.13.0", (api) => {
- extendTopicModel(api);
+ extendTopicModel(api, PLUGIN_ID);
initialize(api);
registerTopicFooterButtons(api);
diff --git a/assets/javascripts/discourse/models/assignment.js b/assets/javascripts/discourse/models/assignment.js
new file mode 100644
index 0000000..eb79234
--- /dev/null
+++ b/assets/javascripts/discourse/models/assignment.js
@@ -0,0 +1,40 @@
+import { tracked } from "@glimmer/tracking";
+import EmberObject from "@ember/object";
+
+export class Assignment extends EmberObject {
+ static fromTopic(topic) {
+ const assignment = new Assignment();
+ assignment.id = 0;
+ assignment.username = topic.assigned_to_user?.username;
+ assignment.groupName = topic.assigned_to_group?.name;
+ assignment.status = topic.assignment_status;
+ assignment.note = topic.assignment_note;
+ assignment.targetId = topic.id;
+ assignment.targetType = "Topic";
+ return assignment;
+ }
+
+ static fromPost(post) {
+ const assignment = new Assignment();
+ assignment.username = post.assigned_to.username;
+ assignment.groupName = post.assigned_to.name;
+ assignment.status = post.assignment_status;
+ assignment.note = post.assignment_note;
+ assignment.targetId = post.postId;
+ assignment.targetType = "Post";
+ assignment.postNumber = post.post_number;
+ assignment.id = post.post_number;
+ return assignment;
+ }
+
+ // to-do rename to groupName, some components use both this model
+ // and models from server, that's why we have to call it "group_name" now
+ @tracked group_name;
+ @tracked username;
+ @tracked status;
+ @tracked note;
+ targetId;
+ targetType;
+ postNumber;
+ isEdited = false;
+}
diff --git a/assets/javascripts/discourse/models/topic.js b/assets/javascripts/discourse/models/topic.js
new file mode 100644
index 0000000..8bf36c9
--- /dev/null
+++ b/assets/javascripts/discourse/models/topic.js
@@ -0,0 +1,67 @@
+import { Assignment } from "./assignment";
+
+export function extendTopicModel(api, pluginId) {
+ api.modifyClass("model:topic", {
+ pluginId,
+
+ assignees() {
+ const result = [];
+
+ if (this.assigned_to_user) {
+ result.push(this.assigned_to_user);
+ }
+
+ const postAssignees = this.assignedPosts().map((p) => p.assigned_to);
+ result.push(...postAssignees);
+ return result;
+ },
+
+ uniqueAssignees() {
+ const map = new Map();
+ this.assignees().forEach((user) => map.set(user.username, user));
+ return [...map.values()];
+ },
+
+ assignedPosts() {
+ if (!this.indirectly_assigned_to) {
+ return [];
+ }
+
+ return Object.entries(this.indirectly_assigned_to).map(([key, value]) => {
+ value.postId = key;
+ return value;
+ });
+ },
+
+ assignments() {
+ return [this.topicAssignment(), ...this.postAssignments()].compact();
+ },
+
+ postAssignments() {
+ if (!this.indirectly_assigned_to) {
+ return [];
+ }
+
+ return Object.entries(this.indirectly_assigned_to).map(([key, value]) => {
+ value.postId = key;
+ return Assignment.fromPost(value);
+ });
+ },
+
+ topicAssignment() {
+ return Assignment.fromTopic(this);
+ },
+
+ isAssigned() {
+ return this.assigned_to_user || this.assigned_to_group;
+ },
+
+ isAssignedTo(user) {
+ return this.assigned_to_user?.username === user.username;
+ },
+
+ hasAssignedPosts() {
+ return !!this.postAssignments().length;
+ },
+ });
+}
diff --git a/assets/javascripts/discourse/services/task-actions.js b/assets/javascripts/discourse/services/task-actions.js
index 465d1ac..1e00a61 100644
--- a/assets/javascripts/discourse/services/task-actions.js
+++ b/assets/javascripts/discourse/services/task-actions.js
@@ -115,4 +115,18 @@ export default class TaskActions extends Service {
popupAjaxError(error);
}
}
+
+ async putAssignment(assignment) {
+ await ajax("/assign/assign", {
+ type: "PUT",
+ data: {
+ username: assignment.username,
+ group_name: assignment.group_name,
+ target_id: assignment.targetId,
+ target_type: assignment.targetType,
+ note: assignment.note,
+ status: assignment.status,
+ },
+ });
+ }
}
diff --git a/assets/stylesheets/assigns.scss b/assets/stylesheets/assigns.scss
index ffd7d4d..1b5fa31 100644
--- a/assets/stylesheets/assigns.scss
+++ b/assets/stylesheets/assigns.scss
@@ -73,6 +73,12 @@
}
}
+ .target {
+ .combo-box {
+ width: 100%;
+ }
+ }
+
.email-group-user-chooser {
width: 100%;
diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml
index 8905016..d0fe9cb 100644
--- a/config/locales/client.en.yml
+++ b/config/locales/client.en.yml
@@ -69,7 +69,9 @@ en:
reassign_title: "Reassign Topic"
assign: "Assign"
assignee_label: Assignee
+ assignment_label: Assignment
choose_assignee: Choose a user to assign.
+ edit_assignments_title: "Edit Assignments"
note_label: Note
optional_label: "(optional)"
status_label: Status
@@ -177,3 +179,7 @@ en:
assign_list_with_unread:
one: "Assign list - %{count} unread assignment"
other: "Assign list - %{count} unread assignments"
+ edit_assignments_modal:
+ title: "Edit assignments"
+ topic: "Topic"
+ post: "Post"
diff --git a/test/javascripts/acceptance/edit-assignments-modal-test.js b/test/javascripts/acceptance/edit-assignments-modal-test.js
new file mode 100644
index 0000000..3f55a9e
--- /dev/null
+++ b/test/javascripts/acceptance/edit-assignments-modal-test.js
@@ -0,0 +1,169 @@
+import { click, settled, visit } from "@ember/test-helpers";
+import { test } from "qunit";
+import {
+ acceptance,
+ publishToMessageBus,
+} from "discourse/tests/helpers/qunit-helpers";
+import topicWithAssignedPosts from "../fixtures/topic-with-assigned-posts";
+
+const topic = topicWithAssignedPosts();
+const firstReply = topic.post_stream.posts[1];
+const secondReply = topic.post_stream.posts[2];
+const new_assignee_1 = "user_1";
+const new_assignee_2 = "user_2";
+
+acceptance("Discourse Assign | Edit assignments modal", function (needs) {
+ needs.user({ can_assign: true });
+ needs.settings({
+ assign_enabled: true,
+ });
+
+ needs.pretender((server, helper) => {
+ server.get("/t/44.json", () => helper.response(topic));
+ server.put("/assign/assign", () => {
+ return helper.response({ success: true });
+ });
+
+ const suggestions = [
+ { username: new_assignee_1 },
+ { username: new_assignee_2 },
+ ];
+ server.get("/assign/suggestions", () =>
+ helper.response({
+ assign_allowed_for_groups: [],
+ suggestions,
+ })
+ );
+ server.get("/u/search/users", () =>
+ helper.response({
+ users: suggestions,
+ })
+ );
+ });
+
+ test("reassigning topic", async function (assert) {
+ await visit("/t/assignment-topic/44");
+ await openModal();
+ await selectAssignee(new_assignee_1);
+
+ await submitModal();
+ await receiveAssignedMessage(topic, new_assignee_1);
+
+ assert
+ .dom(".post-stream article#post_1 .assigned-to .assigned-to--user a")
+ .hasText(new_assignee_1, "The topic is assigned to a new assignee");
+ });
+
+ test("reassigning posts", async function (assert) {
+ await visit("/t/assignment-topic/44");
+ await openModal();
+
+ await selectPost(1);
+ await expandAssigneeChooser();
+ await selectAssignee(new_assignee_1);
+
+ await selectPost(2);
+ await expandAssigneeChooser();
+ await selectAssignee(new_assignee_2);
+
+ await submitModal();
+ await receiveAssignedMessage(firstReply, new_assignee_1);
+ await receiveAssignedMessage(secondReply, new_assignee_2);
+
+ assert
+ .dom(".post-stream article#post_2 .assigned-to .assigned-to-username")
+ .hasText(new_assignee_1, "The first reply is assigned to a new assignee");
+
+ assert
+ .dom(".post-stream article#post_3 .assigned-to .assigned-to-username")
+ .hasText(
+ new_assignee_2,
+ "The second reply is assigned to a new assignee"
+ );
+ });
+
+ test("reassigning topic and posts in one go", async function (assert) {
+ await visit("/t/assignment-topic/44");
+ await openModal();
+ await selectAssignee(new_assignee_1);
+
+ await selectPost(1);
+ await expandAssigneeChooser();
+ await selectAssignee(new_assignee_2);
+
+ await selectPost(2);
+ await expandAssigneeChooser();
+ await selectAssignee(new_assignee_2);
+
+ await submitModal();
+ await receiveAssignedMessage(topic, new_assignee_1);
+ await receiveAssignedMessage(firstReply, new_assignee_2);
+ await receiveAssignedMessage(secondReply, new_assignee_2);
+
+ assert
+ .dom(".post-stream article#post_1 .assigned-to .assigned-to--user a")
+ .hasText(new_assignee_1, "The topic is assigned to a new assignee");
+
+ assert
+ .dom(".post-stream article#post_2 .assigned-to .assigned-to-username")
+ .hasText(new_assignee_2, "The first reply is assigned to a new assignee");
+
+ assert
+ .dom(".post-stream article#post_3 .assigned-to .assigned-to-username")
+ .hasText(
+ new_assignee_2,
+ "The second reply is assigned to a new assignee"
+ );
+ });
+
+ async function expandAssigneeChooser() {
+ await click(
+ ".modal-container #assignee-chooser-header .select-kit-header-wrapper"
+ );
+ }
+
+ async function openModal() {
+ await click("#topic-footer-dropdown-reassign .btn");
+ await click(`li[data-value='reassign']`);
+ }
+
+ // todo remove this function and all calls to it after we start updating UI right away
+ // (there is no need to wait for a message bus message in the browser of a user
+ // who did reassignment, but we do that at the moment)
+ async function receiveAssignedMessage(target, newAssignee) {
+ const targetIsAPost = !!target.topic_id;
+
+ let topicId, postId;
+ if (targetIsAPost) {
+ topicId = target.topic_id;
+ postId = target.id;
+ } else {
+ topicId = target.id;
+ postId = false;
+ }
+
+ await publishToMessageBus("/staff/topic-assignment", {
+ type: "assigned",
+ topic_id: topicId,
+ post_id: postId,
+ assigned_type: "User",
+ assigned_to: {
+ username: newAssignee,
+ },
+ });
+ await settled();
+ }
+
+ async function selectPost(number) {
+ await click(".target .single-select .select-kit-header-wrapper");
+ await click(`li[title='Post #${number}']`);
+ }
+
+ async function selectAssignee(username) {
+ await click(`.email-group-user-chooser-row[data-value='${username}']`);
+ }
+
+ async function submitModal() {
+ await click(".d-modal__footer .btn-primary");
+ }
+});
diff --git a/test/javascripts/acceptance/post-popup-menu-test.js b/test/javascripts/acceptance/post-popup-menu-test.js
index 4dd6637..a85768c 100644
--- a/test/javascripts/acceptance/post-popup-menu-test.js
+++ b/test/javascripts/acceptance/post-popup-menu-test.js
@@ -5,7 +5,7 @@ import {
publishToMessageBus,
updateCurrentUser,
} from "discourse/tests/helpers/qunit-helpers";
-import topicWithAssignedPost from "../fixtures/topic-with-assigned-post";
+import topicWithAssignedPosts from "../fixtures/topic-with-assigned-posts";
const new_assignee_username = "new_assignee";
@@ -23,7 +23,7 @@ const selectors = {
},
};
-const topic = topicWithAssignedPost();
+const topic = topicWithAssignedPosts();
const post = topic.post_stream.posts[1];
acceptance("Discourse Assign | Post popup menu", function (needs) {
diff --git a/test/javascripts/acceptance/topic-level-assign-menu-test.js b/test/javascripts/acceptance/topic-level-assign-menu-test.js
index d57ca3d..2894db5 100644
--- a/test/javascripts/acceptance/topic-level-assign-menu-test.js
+++ b/test/javascripts/acceptance/topic-level-assign-menu-test.js
@@ -5,9 +5,9 @@ import {
publishToMessageBus,
updateCurrentUser,
} from "discourse/tests/helpers/qunit-helpers";
-import topicWithAssignedPost from "../fixtures/topic-with-assigned-post";
+import topicWithAssignedPosts from "../fixtures/topic-with-assigned-posts";
-const topic = topicWithAssignedPost();
+const topic = topicWithAssignedPosts();
const post = topic.post_stream.posts[1];
acceptance("Discourse Assign | Topic level assign menu", function (needs) {
diff --git a/test/javascripts/fixtures/topic-with-assigned-post.js b/test/javascripts/fixtures/topic-with-assigned-post.js
deleted file mode 100644
index 278585a..0000000
--- a/test/javascripts/fixtures/topic-with-assigned-post.js
+++ /dev/null
@@ -1,20 +0,0 @@
-import topicFixtures from "discourse/tests/fixtures/topic";
-import { cloneJSON } from "discourse-common/lib/object";
-
-export default function topicWithAssignedPost() {
- const username = "eviltrout";
- const topic = cloneJSON(topicFixtures["/t/28830/1.json"]);
- const secondPost = topic.post_stream.posts[1];
-
- topic["indirectly_assigned_to"] = {
- [secondPost.id]: {
- assigned_to: {
- username,
- },
- post_number: 1,
- },
- };
- secondPost["assigned_to_user"] = { username };
-
- return topic;
-}
diff --git a/test/javascripts/fixtures/topic-with-assigned-posts.js b/test/javascripts/fixtures/topic-with-assigned-posts.js
new file mode 100644
index 0000000..e977c63
--- /dev/null
+++ b/test/javascripts/fixtures/topic-with-assigned-posts.js
@@ -0,0 +1,28 @@
+import topicFixtures from "discourse/tests/fixtures/topic";
+import { cloneJSON } from "discourse-common/lib/object";
+
+export default function topicWithAssignedPosts() {
+ const username = "eviltrout";
+ const topic = cloneJSON(topicFixtures["/t/28830/1.json"]);
+ const firstReply = topic.post_stream.posts[1];
+ const secondReply = topic.post_stream.posts[2];
+
+ topic["indirectly_assigned_to"] = {
+ [firstReply.id]: {
+ assigned_to: {
+ username,
+ },
+ post_number: 1,
+ },
+ [secondReply.id]: {
+ assigned_to: {
+ username,
+ },
+ post_number: 2,
+ },
+ };
+ firstReply["assigned_to_user"] = { username };
+ secondReply["assigned_to_user"] = { username };
+
+ return topic;
+}