FIX: Various assignment status issues (#536)
This commit is contained in:
parent
9556df664c
commit
5888025dec
|
@ -36,7 +36,7 @@
|
||||||
@id="assign-status"
|
@id="assign-status"
|
||||||
@content={{this.availableStatuses}}
|
@content={{this.availableStatuses}}
|
||||||
@value={{this.status}}
|
@value={{this.status}}
|
||||||
@onChange={{action (mut @model.status)}}
|
@onChange={{fn (mut @model.status)}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
|
@ -26,9 +26,7 @@ export default class AssignUserForm extends Component {
|
||||||
|
|
||||||
get status() {
|
get status() {
|
||||||
return (
|
return (
|
||||||
this.args.model.status ||
|
this.args.model.status || this.siteSettings.assign_statuses.split("|")[0]
|
||||||
this.args.model.target.assignment_status ||
|
|
||||||
this.siteSettings.assign_statuses.split("|")[0]
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
import Component from "@glimmer/component";
|
import Component from "@glimmer/component";
|
||||||
import { action } from "@ember/object";
|
import { action } from "@ember/object";
|
||||||
|
import { TrackedObject } from "@ember-compat/tracked-built-ins";
|
||||||
|
|
||||||
export default class AssignUser extends Component {
|
export default class AssignUser extends Component {
|
||||||
model = {};
|
model = new TrackedObject({});
|
||||||
|
|
||||||
// `submit` property will be mutated by the `AssignUserForm` component
|
// `submit` property will be mutated by the `AssignUserForm` component
|
||||||
formApi = {
|
formApi = {
|
||||||
|
@ -14,6 +15,7 @@ export default class AssignUser extends Component {
|
||||||
return this.args.performAndRefresh({
|
return this.args.performAndRefresh({
|
||||||
type: "assign",
|
type: "assign",
|
||||||
username: this.model.username,
|
username: this.model.username,
|
||||||
|
status: this.model.status,
|
||||||
note: this.model.note,
|
note: this.model.note,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<DModal class="assign" @title={{this.title}} @closeModal={{@closeModal}}>
|
<DModal class="assign" @title={{this.title}} @closeModal={{@closeModal}}>
|
||||||
<:body>
|
<:body>
|
||||||
<AssignUserForm
|
<AssignUserForm
|
||||||
@model={{@model}}
|
@model={{this.model}}
|
||||||
@onSubmit={{this.onSubmit}}
|
@onSubmit={{this.onSubmit}}
|
||||||
@formApi={{this.formApi}}
|
@formApi={{this.formApi}}
|
||||||
/>
|
/>
|
||||||
|
@ -12,7 +12,7 @@
|
||||||
class="btn-primary"
|
class="btn-primary"
|
||||||
@action={{this.formApi.submit}}
|
@action={{this.formApi.submit}}
|
||||||
@label={{if
|
@label={{if
|
||||||
@model.reassign
|
this.model.reassign
|
||||||
"discourse_assign.reassign.title"
|
"discourse_assign.reassign.title"
|
||||||
"discourse_assign.assign_modal.assign"
|
"discourse_assign.assign_modal.assign"
|
||||||
}}
|
}}
|
||||||
|
|
|
@ -1,11 +1,14 @@
|
||||||
import Component from "@glimmer/component";
|
import Component from "@glimmer/component";
|
||||||
import { action } from "@ember/object";
|
import { action } from "@ember/object";
|
||||||
import { inject as service } from "@ember/service";
|
import { inject as service } from "@ember/service";
|
||||||
|
import { TrackedObject } from "@ember-compat/tracked-built-ins";
|
||||||
import I18n from "I18n";
|
import I18n from "I18n";
|
||||||
|
|
||||||
export default class AssignUser extends Component {
|
export default class AssignUser extends Component {
|
||||||
@service taskActions;
|
@service taskActions;
|
||||||
|
|
||||||
|
model = new TrackedObject(this.args.model);
|
||||||
|
|
||||||
// `submit` property will be mutated by the `AssignUserForm` component
|
// `submit` property will be mutated by the `AssignUserForm` component
|
||||||
formApi = {
|
formApi = {
|
||||||
submit() {},
|
submit() {},
|
||||||
|
@ -14,7 +17,7 @@ export default class AssignUser extends Component {
|
||||||
get title() {
|
get title() {
|
||||||
let i18nSuffix;
|
let i18nSuffix;
|
||||||
|
|
||||||
switch (this.args.model.targetType) {
|
switch (this.model.targetType) {
|
||||||
case "Post":
|
case "Post":
|
||||||
i18nSuffix = "_post_modal";
|
i18nSuffix = "_post_modal";
|
||||||
break;
|
break;
|
||||||
|
@ -25,7 +28,7 @@ export default class AssignUser extends Component {
|
||||||
|
|
||||||
return I18n.t(
|
return I18n.t(
|
||||||
`discourse_assign.assign${i18nSuffix}.${
|
`discourse_assign.assign${i18nSuffix}.${
|
||||||
this.args.model.reassign ? "reassign_title" : "title"
|
this.model.reassign ? "reassign_title" : "title"
|
||||||
}`
|
}`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -33,6 +36,6 @@ export default class AssignUser extends Component {
|
||||||
@action
|
@action
|
||||||
async onSubmit() {
|
async onSubmit() {
|
||||||
this.args.closeModal();
|
this.args.closeModal();
|
||||||
await this.taskActions.assign(this.args.model);
|
await this.taskActions.assign(this.model);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -616,7 +616,6 @@ function initialize(api) {
|
||||||
topicAssignee,
|
topicAssignee,
|
||||||
assignedToIndirectly.map((assigned) => ({
|
assignedToIndirectly.map((assigned) => ({
|
||||||
assignee: assigned.assigned_to,
|
assignee: assigned.assigned_to,
|
||||||
status: assigned.assignment_status,
|
|
||||||
note: assigned.assignment_note,
|
note: assigned.assignment_note,
|
||||||
}))
|
}))
|
||||||
)
|
)
|
||||||
|
@ -928,57 +927,23 @@ export default {
|
||||||
|
|
||||||
api.addUserSearchOption("assignableGroups");
|
api.addUserSearchOption("assignableGroups");
|
||||||
|
|
||||||
if (api.addBulkActionButton) {
|
api.addBulkActionButton({
|
||||||
api.addBulkActionButton({
|
label: "topics.bulk.assign",
|
||||||
label: "topics.bulk.assign",
|
icon: "user-plus",
|
||||||
icon: "user-plus",
|
class: "btn-default assign-topics",
|
||||||
class: "btn-default assign-topics",
|
action({ setComponent }) {
|
||||||
action({ setComponent }) {
|
setComponent(BulkAssign);
|
||||||
setComponent(BulkAssign);
|
},
|
||||||
},
|
});
|
||||||
});
|
|
||||||
|
|
||||||
api.addBulkActionButton({
|
api.addBulkActionButton({
|
||||||
label: "topics.bulk.unassign",
|
label: "topics.bulk.unassign",
|
||||||
icon: "user-times",
|
icon: "user-times",
|
||||||
class: "btn-default unassign-topics",
|
class: "btn-default unassign-topics",
|
||||||
action({ performAndRefresh }) {
|
action({ performAndRefresh }) {
|
||||||
performAndRefresh({ type: "unassign" });
|
performAndRefresh({ type: "unassign" });
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
} else {
|
|
||||||
// TODO: Remove this path after core 3.1.0.beta7 is released
|
|
||||||
const {
|
|
||||||
default: TopicButtonAction,
|
|
||||||
addBulkButton,
|
|
||||||
} = require("discourse/controllers/topic-bulk-actions");
|
|
||||||
|
|
||||||
TopicButtonAction.reopen({
|
|
||||||
actions: {
|
|
||||||
showReAssign() {
|
|
||||||
const controller = getOwner(this).lookup(
|
|
||||||
"controller:bulk-assign"
|
|
||||||
);
|
|
||||||
controller.set("model", { username: "", note: "" });
|
|
||||||
this.send("changeBulkTemplate", "modal/bulk-assign");
|
|
||||||
},
|
|
||||||
|
|
||||||
unassignTopics() {
|
|
||||||
this.performAndRefresh({ type: "unassign" });
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
addBulkButton("showReAssign", "assign", {
|
|
||||||
icon: "user-plus",
|
|
||||||
class: "btn-default assign-topics",
|
|
||||||
});
|
|
||||||
|
|
||||||
addBulkButton("unassignTopics", "unassign", {
|
|
||||||
icon: "user-times",
|
|
||||||
class: "btn-default unassign-topics",
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -66,13 +66,8 @@
|
||||||
margin-left: 5px;
|
margin-left: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.modal.assign {
|
.d-modal.assign {
|
||||||
.modal-inner-container {
|
.d-modal__body {
|
||||||
width: 400px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.d-modal__body,
|
|
||||||
.modal-body {
|
|
||||||
overflow-y: unset;
|
overflow-y: unset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -223,14 +223,15 @@ class ::Assigner
|
||||||
|
|
||||||
def update_details(assign_to, note, status, skip_small_action_post: false)
|
def update_details(assign_to, note, status, skip_small_action_post: false)
|
||||||
case
|
case
|
||||||
when @target.assignment.note != note && @target.assignment.status != status && status.present?
|
when note.present? && status.present? && @target.assignment.note != note &&
|
||||||
|
@target.assignment.status != status
|
||||||
small_action_text = <<~TEXT
|
small_action_text = <<~TEXT
|
||||||
Status: #{@target.assignment.status} → #{status}
|
Status: #{@target.assignment.status} → #{status}
|
||||||
|
|
||||||
#{note}
|
#{note}
|
||||||
TEXT
|
TEXT
|
||||||
change_type = "details"
|
change_type = "details"
|
||||||
when @target.assignment.note != note
|
when note.present? && @target.assignment.note != note
|
||||||
small_action_text = note
|
small_action_text = note
|
||||||
change_type = "note"
|
change_type = "note"
|
||||||
when @target.assignment.status != status
|
when @target.assignment.status != status
|
||||||
|
|
|
@ -645,7 +645,11 @@ after_initialize do
|
||||||
if @user.can_assign?
|
if @user.can_assign?
|
||||||
assign_user = User.find_by_username(@operation[:username])
|
assign_user = User.find_by_username(@operation[:username])
|
||||||
topics.each do |topic|
|
topics.each do |topic|
|
||||||
Assigner.new(topic, @user).assign(assign_user, note: @operation[:note])
|
Assigner.new(topic, @user).assign(
|
||||||
|
assign_user,
|
||||||
|
status: @operation[:status],
|
||||||
|
note: @operation[:note],
|
||||||
|
)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -657,6 +661,7 @@ after_initialize do
|
||||||
end
|
end
|
||||||
|
|
||||||
register_permitted_bulk_action_parameter :username
|
register_permitted_bulk_action_parameter :username
|
||||||
|
register_permitted_bulk_action_parameter :status
|
||||||
register_permitted_bulk_action_parameter :note
|
register_permitted_bulk_action_parameter :note
|
||||||
|
|
||||||
add_to_class(:user_bookmark_base_serializer, :assigned_to) do
|
add_to_class(:user_bookmark_base_serializer, :assigned_to) do
|
||||||
|
|
|
@ -44,7 +44,7 @@ acceptance("Discourse Assign | Assign mobile", function (needs) {
|
||||||
|
|
||||||
assert.true(menu.rowByValue("assign").exists());
|
assert.true(menu.rowByValue("assign").exists());
|
||||||
await menu.selectRowByValue("assign");
|
await menu.selectRowByValue("assign");
|
||||||
assert.dom(".assign.modal").exists("assign modal opens");
|
assert.dom(".assign.d-modal").exists("assign modal opens");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -86,12 +86,12 @@ acceptance("Discourse Assign | Assign desktop", function (needs) {
|
||||||
.exists("assign to post button exists");
|
.exists("assign to post button exists");
|
||||||
|
|
||||||
await click("#post_2 .extra-buttons .d-icon-user-plus");
|
await click("#post_2 .extra-buttons .d-icon-user-plus");
|
||||||
assert.dom(".assign.modal").exists("assign modal opens");
|
assert.dom(".assign.d-modal").exists("assign modal opens");
|
||||||
|
|
||||||
const menu = selectKit(".assign.modal .user-chooser");
|
const menu = selectKit(".assign.d-modal .user-chooser");
|
||||||
assert.true(menu.isExpanded(), "user selector is expanded");
|
assert.true(menu.isExpanded(), "user selector is expanded");
|
||||||
|
|
||||||
await click(".assign.modal .btn-primary");
|
await click(".assign.d-modal .btn-primary");
|
||||||
assert.dom(".error-label").includesText("Choose a user to assign");
|
assert.dom(".error-label").includesText("Choose a user to assign");
|
||||||
|
|
||||||
await menu.expand();
|
await menu.expand();
|
||||||
|
@ -108,16 +108,16 @@ acceptance("Discourse Assign | Assign desktop", function (needs) {
|
||||||
});
|
});
|
||||||
|
|
||||||
await fillIn("#assign-modal-note", "a note!");
|
await fillIn("#assign-modal-note", "a note!");
|
||||||
await click(".assign.modal .btn-primary");
|
await click(".assign.d-modal .btn-primary");
|
||||||
|
|
||||||
assert.dom(".assign.modal").doesNotExist("assign modal closes");
|
assert.dom(".assign.d-modal").doesNotExist("assign modal closes");
|
||||||
});
|
});
|
||||||
|
|
||||||
test("Footer dropdown contains button", async function (assert) {
|
test("Footer dropdown contains button", async function (assert) {
|
||||||
await visit("/t/internationalization-localization/280");
|
await visit("/t/internationalization-localization/280");
|
||||||
await click("#topic-footer-button-assign");
|
await click("#topic-footer-button-assign");
|
||||||
|
|
||||||
assert.dom(".assign.modal").exists("assign modal opens");
|
assert.dom(".assign.d-modal").exists("assign modal opens");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -151,12 +151,35 @@ acceptance("Discourse Assign | Assign Status enabled", function (needs) {
|
||||||
});
|
});
|
||||||
|
|
||||||
test("Modal contains status dropdown", async function (assert) {
|
test("Modal contains status dropdown", async function (assert) {
|
||||||
|
pretender.put("/assign/assign", ({ requestBody }) => {
|
||||||
|
const body = parsePostData(requestBody);
|
||||||
|
assert.strictEqual(body.target_type, "Topic");
|
||||||
|
assert.strictEqual(body.target_id, "280");
|
||||||
|
assert.strictEqual(body.username, "eviltrout");
|
||||||
|
assert.strictEqual(body.status, "In Progress");
|
||||||
|
|
||||||
|
return response({ success: true });
|
||||||
|
});
|
||||||
|
|
||||||
await visit("/t/internationalization-localization/280");
|
await visit("/t/internationalization-localization/280");
|
||||||
await click("#topic-footer-button-assign");
|
await click("#topic-footer-button-assign");
|
||||||
|
|
||||||
assert
|
assert
|
||||||
.dom(".assign.modal #assign-status")
|
.dom(".assign.d-modal #assign-status")
|
||||||
.exists("assign status dropdown exists");
|
.exists("assign status dropdown exists");
|
||||||
|
|
||||||
|
const statusDropdown = selectKit("#assign-status");
|
||||||
|
assert.strictEqual(statusDropdown.header().value(), "New");
|
||||||
|
|
||||||
|
await statusDropdown.expand();
|
||||||
|
await statusDropdown.selectRowByValue("In Progress");
|
||||||
|
assert.strictEqual(statusDropdown.header().value(), "In Progress");
|
||||||
|
|
||||||
|
const menu = selectKit(".assign.d-modal .user-chooser");
|
||||||
|
await menu.expand();
|
||||||
|
await menu.selectRowByIndex(0);
|
||||||
|
|
||||||
|
await click(".assign.d-modal .btn-primary");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -190,7 +213,7 @@ acceptance("Discourse Assign | Assign Status disabled", function (needs) {
|
||||||
await click("#topic-footer-button-assign");
|
await click("#topic-footer-button-assign");
|
||||||
|
|
||||||
assert
|
assert
|
||||||
.dom(".assign.modal #assign-status")
|
.dom(".assign.d-modal #assign-status")
|
||||||
.doesNotExist("assign status dropdown doesn't exists");
|
.doesNotExist("assign status dropdown doesn't exists");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -13,7 +13,10 @@ acceptance("Discourse Assign | Bulk actions", function (needs) {
|
||||||
moderator: true,
|
moderator: true,
|
||||||
can_assign: true,
|
can_assign: true,
|
||||||
});
|
});
|
||||||
needs.settings({ assign_enabled: true });
|
needs.settings({
|
||||||
|
assign_enabled: true,
|
||||||
|
enable_assign_status: true,
|
||||||
|
});
|
||||||
|
|
||||||
needs.pretender((server, helper) => {
|
needs.pretender((server, helper) => {
|
||||||
server.get("/assign/suggestions", () => {
|
server.get("/assign/suggestions", () => {
|
||||||
|
@ -35,6 +38,22 @@ acceptance("Discourse Assign | Bulk actions", function (needs) {
|
||||||
});
|
});
|
||||||
|
|
||||||
test("Assigning users to topics", async function (assert) {
|
test("Assigning users to topics", async function (assert) {
|
||||||
|
pretender.put("/topics/bulk", ({ requestBody }) => {
|
||||||
|
const body = parsePostData(requestBody);
|
||||||
|
assert.deepEqual(body.operation, {
|
||||||
|
type: "assign",
|
||||||
|
username: "eviltrout",
|
||||||
|
status: "In Progress",
|
||||||
|
note: "a note!",
|
||||||
|
});
|
||||||
|
assert.deepEqual(body["topic_ids[]"], [
|
||||||
|
topic1.dataset.topicId,
|
||||||
|
topic2.dataset.topicId,
|
||||||
|
]);
|
||||||
|
|
||||||
|
return response({ success: true });
|
||||||
|
});
|
||||||
|
|
||||||
await visit("/latest");
|
await visit("/latest");
|
||||||
await click("button.bulk-select");
|
await click("button.bulk-select");
|
||||||
|
|
||||||
|
@ -61,22 +80,15 @@ acceptance("Discourse Assign | Bulk actions", function (needs) {
|
||||||
await menu.selectRowByIndex(0);
|
await menu.selectRowByIndex(0);
|
||||||
assert.strictEqual(menu.header().value(), "eviltrout");
|
assert.strictEqual(menu.header().value(), "eviltrout");
|
||||||
|
|
||||||
pretender.put("/topics/bulk", ({ requestBody }) => {
|
|
||||||
const body = parsePostData(requestBody);
|
|
||||||
assert.deepEqual(body.operation, {
|
|
||||||
type: "assign",
|
|
||||||
username: "eviltrout",
|
|
||||||
note: "a note!",
|
|
||||||
});
|
|
||||||
assert.deepEqual(body["topic_ids[]"], [
|
|
||||||
topic1.dataset.topicId,
|
|
||||||
topic2.dataset.topicId,
|
|
||||||
]);
|
|
||||||
|
|
||||||
return response({ success: true });
|
|
||||||
});
|
|
||||||
|
|
||||||
await fillIn("#assign-modal-note", "a note!");
|
await fillIn("#assign-modal-note", "a note!");
|
||||||
|
|
||||||
|
const statusDropdown = selectKit("#assign-status");
|
||||||
|
assert.strictEqual(statusDropdown.header().value(), "New");
|
||||||
|
|
||||||
|
await statusDropdown.expand();
|
||||||
|
await statusDropdown.selectRowByValue("In Progress");
|
||||||
|
assert.strictEqual(statusDropdown.header().value(), "In Progress");
|
||||||
|
|
||||||
await click(".topic-bulk-actions-modal .btn-primary");
|
await click(".topic-bulk-actions-modal .btn-primary");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue