DEV: Add compatibility with the Glimmer Post Stream (#651)
This commit is contained in:
parent
bf52519dc7
commit
bbb5147062
|
@ -0,0 +1,124 @@
|
|||
import Component from "@glimmer/component";
|
||||
import { service } from "@ember/service";
|
||||
import { htmlSafe } from "@ember/template";
|
||||
import icon from "discourse/helpers/d-icon";
|
||||
import { bind } from "discourse/lib/decorators";
|
||||
import { i18n } from "discourse-i18n";
|
||||
import { assignedToGroupPath, assignedToUserPath } from "../lib/url";
|
||||
|
||||
export default class AssignedToFirstPost extends Component {
|
||||
@service siteSettings;
|
||||
|
||||
get assignedToUser() {
|
||||
return this.args.post?.topic?.assigned_to_user;
|
||||
}
|
||||
|
||||
get assignedToGroup() {
|
||||
return this.args.post?.topic?.assigned_to_group;
|
||||
}
|
||||
|
||||
get icon() {
|
||||
return this.assignedToUser ? "user-plus" : "group-plus";
|
||||
}
|
||||
|
||||
get indirectlyAssignedTo() {
|
||||
return this.args.post?.topic?.indirectly_assigned_to;
|
||||
}
|
||||
|
||||
get indirectAssignments() {
|
||||
if (!this.indirectlyAssignedTo) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return Object.keys(this.indirectlyAssignedTo).map((postId) => {
|
||||
const postNumber = this.indirectlyAssignedTo[postId].post_number;
|
||||
|
||||
return {
|
||||
postId,
|
||||
assignee: this.indirectlyAssignedTo[postId].assigned_to,
|
||||
postNumber,
|
||||
url: `${this.args.post.topic.url}/${postNumber}`,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
get isAssigned() {
|
||||
return !!(
|
||||
this.assignedToUser ||
|
||||
this.assignedToGroup ||
|
||||
this.args.post?.topic?.indirectly_assigned_to
|
||||
);
|
||||
}
|
||||
|
||||
get hasOnlyIndirectAssignments() {
|
||||
return !this.assignedToUser && !this.assignedToGroup;
|
||||
}
|
||||
|
||||
@bind
|
||||
prioritizedAssigneeName(assignee) {
|
||||
// if this code is ever replaced to use `prioritize_username_in_ux`, remove this function and use the helper
|
||||
// userPrioritizedName instead
|
||||
return this.siteSettings.prioritize_full_name_in_ux || !assignee.username
|
||||
? assignee.name || assignee.username
|
||||
: assignee.username;
|
||||
}
|
||||
|
||||
<template>
|
||||
{{#if this.isAssigned}}
|
||||
<p class="assigned-to">
|
||||
{{icon this.icon}}
|
||||
{{#if this.assignedToUser}}
|
||||
<span class="assignee">
|
||||
<span class="assigned-to--user">
|
||||
{{htmlSafe
|
||||
(i18n
|
||||
"discourse_assign.assigned_topic_to"
|
||||
username=(this.prioritizedAssigneeName this.assignedToUser)
|
||||
path=(assignedToUserPath this.assignedToUser)
|
||||
)
|
||||
}}
|
||||
</span>
|
||||
</span>
|
||||
{{/if}}
|
||||
|
||||
{{#if this.assignedToGroup}}
|
||||
<span class="assignee">
|
||||
<span class="assigned-to--group">
|
||||
{{htmlSafe
|
||||
(i18n
|
||||
"discourse_assign.assigned_topic_to"
|
||||
username=this.assignedToGroup.name
|
||||
path=(assignedToGroupPath this.assignedToGroup)
|
||||
)
|
||||
}}
|
||||
</span>
|
||||
</span>
|
||||
{{/if}}
|
||||
|
||||
{{#if this.hasOnlyIndirectAssignments}}
|
||||
<span class="assign-text">
|
||||
{{i18n "discourse_assign.assigned"}}
|
||||
</span>
|
||||
{{/if}}
|
||||
{{#if this.indirectlyAssignedTo}}
|
||||
{{#each
|
||||
this.indirectAssignments key="postId"
|
||||
as |indirectAssignment|
|
||||
}}
|
||||
<span class="assignee">
|
||||
<a href={{indirectAssignment.url}} class="assigned-indirectly">
|
||||
{{i18n
|
||||
"discourse_assign.assign_post_to_multiple"
|
||||
post_number=indirectAssignment.postNumber
|
||||
username=(this.prioritizedAssigneeName
|
||||
indirectAssignment.assignee
|
||||
)
|
||||
}}
|
||||
</a>
|
||||
</span>
|
||||
{{/each}}
|
||||
{{/if}}
|
||||
</p>
|
||||
{{/if}}
|
||||
</template>
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
import Component from "@glimmer/component";
|
||||
import { assignedToGroupPath, assignedToUserPath } from "../lib/url";
|
||||
import AssignedFirstPost from "./assigned-to-first-post";
|
||||
import AssignedToPost from "./assigned-to-post";
|
||||
|
||||
export default class PostAssignmentsDisplay extends Component {
|
||||
static shouldRender(args) {
|
||||
return args.post;
|
||||
}
|
||||
|
||||
get post() {
|
||||
return this.args.outletArgs.post;
|
||||
}
|
||||
|
||||
get assignedTo() {
|
||||
return this.post.topic?.indirectly_assigned_to?.[this.post.id]?.assigned_to;
|
||||
}
|
||||
|
||||
get assignedToUser() {
|
||||
return this.assignedTo.username ? this.assignedTo : null;
|
||||
}
|
||||
|
||||
get assignedToGroup() {
|
||||
return !this.assignedToUser && this.assignedTo.name
|
||||
? this.assignedTo
|
||||
: null;
|
||||
}
|
||||
|
||||
get assignedHref() {
|
||||
return this.assignedToUser
|
||||
? assignedToUserPath(this.assignedToUser)
|
||||
: assignedToGroupPath(this.assignedToGroup);
|
||||
}
|
||||
|
||||
<template>
|
||||
{{#if this.post.firstPost}}
|
||||
<AssignedFirstPost @post={{this.post}} />
|
||||
{{else if this.assignedTo}}
|
||||
<p class="assigned-to">
|
||||
<AssignedToPost
|
||||
@assignedToUser={{this.assignedToUser}}
|
||||
@assignedToGroup={{this.assignedToGroup}}
|
||||
@href={{this.assignedHref}}
|
||||
@post={{this.post}}
|
||||
/>
|
||||
</p>
|
||||
{{/if}}
|
||||
</template>
|
||||
}
|
|
@ -6,6 +6,7 @@ import { hbs } from "ember-cli-htmlbars";
|
|||
import { h } from "virtual-dom";
|
||||
import { renderAvatar } from "discourse/helpers/user-avatar";
|
||||
import discourseComputed from "discourse/lib/decorators";
|
||||
import { withSilencedDeprecations } from "discourse/lib/deprecated";
|
||||
import getURL from "discourse/lib/get-url";
|
||||
import { iconHTML, iconNode } from "discourse/lib/icon-library";
|
||||
import { withPluginApi } from "discourse/lib/plugin-api";
|
||||
|
@ -18,7 +19,9 @@ import { i18n } from "discourse-i18n";
|
|||
import AssignButton from "../components/assign-button";
|
||||
import BulkActionsAssignUser from "../components/bulk-actions/bulk-assign-user";
|
||||
import EditTopicAssignments from "../components/modal/edit-topic-assignments";
|
||||
import PostAssignmentsDisplay from "../components/post-assignments-display";
|
||||
import TopicLevelAssignMenu from "../components/topic-level-assign-menu";
|
||||
import { assignedToGroupPath, assignedToUserPath } from "../lib/url";
|
||||
import { extendTopicModel } from "../models/topic";
|
||||
|
||||
const DEPENDENT_KEYS = [
|
||||
|
@ -321,12 +324,6 @@ function initialize(api) {
|
|||
}
|
||||
}
|
||||
|
||||
api.addPostSmallActionClassesCallback((post) => {
|
||||
if (post.actionCode.includes("assigned") && !siteSettings.assigns_public) {
|
||||
return ["private-assign"];
|
||||
}
|
||||
});
|
||||
|
||||
api.addAdvancedSearchOptions(
|
||||
api.getCurrentUser()?.can_assign
|
||||
? {
|
||||
|
@ -344,19 +341,6 @@ function initialize(api) {
|
|||
: {}
|
||||
);
|
||||
|
||||
function assignedToUserPath(assignedToUser) {
|
||||
return getURL(
|
||||
siteSettings.assigns_user_url_path.replace(
|
||||
"{username}",
|
||||
assignedToUser.username
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
function assignedToGroupPath(assignedToGroup) {
|
||||
return getURL(`/g/${assignedToGroup.name}/assigned/everyone`);
|
||||
}
|
||||
|
||||
api.modifyClass(
|
||||
"model:bookmark",
|
||||
(Superclass) =>
|
||||
|
@ -391,41 +375,6 @@ function initialize(api) {
|
|||
}
|
||||
);
|
||||
|
||||
api.addPostSmallActionIcon("assigned", "user-plus");
|
||||
api.addPostSmallActionIcon("assigned_to_post", "user-plus");
|
||||
api.addPostSmallActionIcon("assigned_group", "group-plus");
|
||||
api.addPostSmallActionIcon("assigned_group_to_post", "group-plus");
|
||||
api.addPostSmallActionIcon("unassigned", "user-xmark");
|
||||
api.addPostSmallActionIcon("unassigned_group", "group-times");
|
||||
api.addPostSmallActionIcon("unassigned_from_post", "user-xmark");
|
||||
api.addPostSmallActionIcon("unassigned_group_from_post", "group-times");
|
||||
api.includePostAttributes("assigned_to_user", "assigned_to_group");
|
||||
api.addPostSmallActionIcon("reassigned", "user-plus");
|
||||
api.addPostSmallActionIcon("reassigned_group", "group-plus");
|
||||
|
||||
api.addPostTransformCallback((transformed) => {
|
||||
if (
|
||||
[
|
||||
"assigned",
|
||||
"unassigned",
|
||||
"reassigned",
|
||||
"assigned_group",
|
||||
"unassigned_group",
|
||||
"reassigned_group",
|
||||
"assigned_to_post",
|
||||
"assigned_group_to_post",
|
||||
"unassigned_from_post",
|
||||
"unassigned_group_from_post",
|
||||
"details_change",
|
||||
"note_change",
|
||||
"status_change",
|
||||
].includes(transformed.actionCode)
|
||||
) {
|
||||
transformed.isSmallAction = true;
|
||||
transformed.canEdit = true;
|
||||
}
|
||||
});
|
||||
|
||||
api.addDiscoveryQueryParam("assigned", { replace: true, refreshModel: true });
|
||||
|
||||
api.addTagsHtmlCallback((topic, params = {}) => {
|
||||
|
@ -518,119 +467,6 @@ function initialize(api) {
|
|||
return result;
|
||||
});
|
||||
|
||||
api.createWidget("assigned-to-post", {
|
||||
html(attrs) {
|
||||
return new RenderGlimmer(
|
||||
this,
|
||||
"p.assigned-to",
|
||||
hbs`
|
||||
<AssignedToPost @assignedToUser={{@data.assignedToUser}} @assignedToGroup={{@data.assignedToGroup}}
|
||||
@href={{@data.href}} @post={{@data.post}} />`,
|
||||
{
|
||||
assignedToUser: attrs.post.assigned_to_user,
|
||||
assignedToGroup: attrs.post.assigned_to_group,
|
||||
href: attrs.href,
|
||||
post: attrs.post,
|
||||
}
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
api.createWidget("assigned-to-first-post", {
|
||||
html(attrs) {
|
||||
const topic = attrs.topic;
|
||||
const [assignedToUser, assignedToGroup, indirectlyAssignedTo] = [
|
||||
topic.assigned_to_user,
|
||||
topic.assigned_to_group,
|
||||
topic.indirectly_assigned_to,
|
||||
];
|
||||
const assigneeElements = [];
|
||||
|
||||
const assignedHtml = (username, path, type) => {
|
||||
return `<span class="assigned-to--${type}">${htmlSafe(
|
||||
i18n("discourse_assign.assigned_topic_to", {
|
||||
username,
|
||||
path,
|
||||
})
|
||||
)}</span>`;
|
||||
};
|
||||
|
||||
let displayedName = "";
|
||||
if (assignedToUser) {
|
||||
displayedName = this.siteSettings.prioritize_full_name_in_ux
|
||||
? assignedToUser.name || assignedToUser.username
|
||||
: assignedToUser.username;
|
||||
|
||||
assigneeElements.push(
|
||||
h(
|
||||
"span.assignee",
|
||||
new RawHtml({
|
||||
html: assignedHtml(
|
||||
displayedName,
|
||||
assignedToUserPath(assignedToUser),
|
||||
"user"
|
||||
),
|
||||
})
|
||||
)
|
||||
);
|
||||
}
|
||||
if (assignedToGroup) {
|
||||
assigneeElements.push(
|
||||
h(
|
||||
"span.assignee",
|
||||
new RawHtml({
|
||||
html: assignedHtml(
|
||||
assignedToGroup.name,
|
||||
assignedToGroupPath(assignedToGroup),
|
||||
"group"
|
||||
),
|
||||
})
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if (indirectlyAssignedTo) {
|
||||
Object.keys(indirectlyAssignedTo).map((postId) => {
|
||||
const assignee = indirectlyAssignedTo[postId].assigned_to;
|
||||
const postNumber = indirectlyAssignedTo[postId].post_number;
|
||||
|
||||
displayedName =
|
||||
this.siteSettings.prioritize_full_name_in_ux || !assignee.username
|
||||
? assignee.name || assignee.username
|
||||
: assignee.username;
|
||||
|
||||
assigneeElements.push(
|
||||
h("span.assignee", [
|
||||
h(
|
||||
"a",
|
||||
{
|
||||
attributes: {
|
||||
class: "assigned-indirectly",
|
||||
href: `${topic.url}/${postNumber}`,
|
||||
},
|
||||
},
|
||||
i18n("discourse_assign.assign_post_to_multiple", {
|
||||
post_number: postNumber,
|
||||
username: displayedName,
|
||||
})
|
||||
),
|
||||
])
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
if (!isEmpty(assigneeElements)) {
|
||||
return h("p.assigned-to", [
|
||||
assignedToUser ? iconNode("user-plus") : iconNode("group-plus"),
|
||||
assignedToUser || assignedToGroup
|
||||
? ""
|
||||
: h("span.assign-text", i18n("discourse_assign.assigned")),
|
||||
assigneeElements,
|
||||
]);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
api.modifyClass(
|
||||
"model:group",
|
||||
(Superclass) =>
|
||||
|
@ -717,6 +553,86 @@ function initialize(api) {
|
|||
}
|
||||
);
|
||||
|
||||
customizePost(api, siteSettings);
|
||||
|
||||
api.replaceIcon("notification.assigned", "user-plus");
|
||||
|
||||
api.replaceIcon(
|
||||
"notification.discourse_assign.assign_group_notification",
|
||||
"group-plus"
|
||||
);
|
||||
|
||||
api.modifyClass(
|
||||
"controller:preferences/notifications",
|
||||
(Superclass) =>
|
||||
class extends Superclass {
|
||||
@action
|
||||
save() {
|
||||
this.saveAttrNames.push("custom_fields");
|
||||
super.save(...arguments);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
api.addKeyboardShortcut("g a", "", { path: "/my/activity/assigned" });
|
||||
}
|
||||
|
||||
function customizePost(api, siteSettings) {
|
||||
api.addTrackedPostProperties("assigned_to_user", "assigned_to_group");
|
||||
|
||||
api.modifyClass(
|
||||
"model:post",
|
||||
(Superclass) =>
|
||||
class extends Superclass {
|
||||
get can_edit() {
|
||||
return isAssignSmallAction(this.action_code) ? true : super.can_edit;
|
||||
}
|
||||
|
||||
// overriding tracked properties requires overriding both the getter and the setter.
|
||||
// otherwise the superclass will throw an error when the application sets the field value
|
||||
set can_edit(value) {
|
||||
super.can_edit = value;
|
||||
}
|
||||
|
||||
get isSmallAction() {
|
||||
return isAssignSmallAction(this.action_code)
|
||||
? true
|
||||
: super.isSmallAction;
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
api.renderAfterWrapperOutlet(
|
||||
"post-content-cooked-html",
|
||||
PostAssignmentsDisplay
|
||||
);
|
||||
|
||||
api.addPostSmallActionClassesCallback((post) => {
|
||||
// TODO (glimmer-post-stream): only check for .action_code once the widget code is removed
|
||||
const actionCode = post.action_code || post.actionCode;
|
||||
|
||||
if (actionCode.includes("assigned") && !siteSettings.assigns_public) {
|
||||
return ["private-assign"];
|
||||
}
|
||||
});
|
||||
|
||||
api.addPostSmallActionIcon("assigned", "user-plus");
|
||||
api.addPostSmallActionIcon("assigned_to_post", "user-plus");
|
||||
api.addPostSmallActionIcon("assigned_group", "group-plus");
|
||||
api.addPostSmallActionIcon("assigned_group_to_post", "group-plus");
|
||||
api.addPostSmallActionIcon("unassigned", "user-xmark");
|
||||
api.addPostSmallActionIcon("unassigned_group", "group-times");
|
||||
api.addPostSmallActionIcon("unassigned_from_post", "user-xmark");
|
||||
api.addPostSmallActionIcon("unassigned_group_from_post", "group-times");
|
||||
api.addPostSmallActionIcon("reassigned", "user-plus");
|
||||
api.addPostSmallActionIcon("reassigned_group", "group-plus");
|
||||
|
||||
withSilencedDeprecations("discourse.post-stream-widget-overrides", () =>
|
||||
customizeWidgetPost(api)
|
||||
);
|
||||
}
|
||||
|
||||
function customizeWidgetPost(api) {
|
||||
api.decorateWidget("post-contents:after-cooked", (dec) => {
|
||||
const postModel = dec.getModel();
|
||||
if (postModel) {
|
||||
|
@ -752,26 +668,146 @@ function initialize(api) {
|
|||
}
|
||||
});
|
||||
|
||||
api.replaceIcon("notification.assigned", "user-plus");
|
||||
|
||||
api.replaceIcon(
|
||||
"notification.discourse_assign.assign_group_notification",
|
||||
"group-plus"
|
||||
);
|
||||
|
||||
api.modifyClass(
|
||||
"controller:preferences/notifications",
|
||||
(Superclass) =>
|
||||
class extends Superclass {
|
||||
@action
|
||||
save() {
|
||||
this.saveAttrNames.push("custom_fields");
|
||||
super.save(...arguments);
|
||||
api.createWidget("assigned-to-post", {
|
||||
html(attrs) {
|
||||
return new RenderGlimmer(
|
||||
this,
|
||||
"p.assigned-to",
|
||||
hbs`
|
||||
<AssignedToPost @assignedToUser={{@data.assignedToUser}} @assignedToGroup={{@data.assignedToGroup}}
|
||||
@href={{@data.href}} @post={{@data.post}} />`,
|
||||
{
|
||||
assignedToUser: attrs.post.assigned_to_user,
|
||||
assignedToGroup: attrs.post.assigned_to_group,
|
||||
href: attrs.href,
|
||||
post: attrs.post,
|
||||
}
|
||||
}
|
||||
);
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
api.addKeyboardShortcut("g a", "", { path: "/my/activity/assigned" });
|
||||
api.createWidget("assigned-to-first-post", {
|
||||
html(attrs) {
|
||||
const topic = attrs.topic;
|
||||
const [assignedToUser, assignedToGroup, indirectlyAssignedTo] = [
|
||||
topic.assigned_to_user,
|
||||
topic.assigned_to_group,
|
||||
topic.indirectly_assigned_to,
|
||||
];
|
||||
const assigneeElements = [];
|
||||
|
||||
const assignedHtml = (username, path, type) => {
|
||||
return `<span class="assigned-to--${type}">${htmlSafe(
|
||||
i18n("discourse_assign.assigned_topic_to", {
|
||||
username,
|
||||
path,
|
||||
})
|
||||
)}</span>`;
|
||||
};
|
||||
|
||||
let displayedName = "";
|
||||
if (assignedToUser) {
|
||||
displayedName = this.siteSettings.prioritize_full_name_in_ux
|
||||
? assignedToUser.name || assignedToUser.username
|
||||
: assignedToUser.username;
|
||||
|
||||
assigneeElements.push(
|
||||
h(
|
||||
"span.assignee",
|
||||
new RawHtml({
|
||||
html: assignedHtml(
|
||||
displayedName,
|
||||
assignedToUserPath(assignedToUser),
|
||||
"user"
|
||||
),
|
||||
})
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if (assignedToGroup) {
|
||||
assigneeElements.push(
|
||||
h(
|
||||
"span.assignee",
|
||||
new RawHtml({
|
||||
html: assignedHtml(
|
||||
assignedToGroup.name,
|
||||
assignedToGroupPath(assignedToGroup),
|
||||
"group"
|
||||
),
|
||||
})
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if (indirectlyAssignedTo) {
|
||||
Object.keys(indirectlyAssignedTo).map((postId) => {
|
||||
const assignee = indirectlyAssignedTo[postId].assigned_to;
|
||||
const postNumber = indirectlyAssignedTo[postId].post_number;
|
||||
|
||||
displayedName =
|
||||
!this.siteSettings.prioritize_username_in_ux || !assignee.username
|
||||
? assignee.name || assignee.username
|
||||
: assignee.username;
|
||||
|
||||
assigneeElements.push(
|
||||
h("span.assignee", [
|
||||
h(
|
||||
"a",
|
||||
{
|
||||
attributes: {
|
||||
class: "assigned-indirectly",
|
||||
href: `${topic.url}/${postNumber}`,
|
||||
},
|
||||
},
|
||||
i18n("discourse_assign.assign_post_to_multiple", {
|
||||
post_number: postNumber,
|
||||
username: displayedName,
|
||||
})
|
||||
),
|
||||
])
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
if (!isEmpty(assigneeElements)) {
|
||||
return h("p.assigned-to", [
|
||||
assignedToUser ? iconNode("user-plus") : iconNode("group-plus"),
|
||||
assignedToUser || assignedToGroup
|
||||
? ""
|
||||
: h("span.assign-text", i18n("discourse_assign.assigned")),
|
||||
assigneeElements,
|
||||
]);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
// `addPostTransformCallback` doesn't have a direct translation in the new Glimmer API.
|
||||
// We need to use a modify class in the post model instead
|
||||
api.addPostTransformCallback((transformed) => {
|
||||
if (isAssignSmallAction(transformed.actionCode)) {
|
||||
transformed.isSmallAction = true;
|
||||
transformed.canEdit = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function isAssignSmallAction(actionCode) {
|
||||
return [
|
||||
"assigned",
|
||||
"unassigned",
|
||||
"reassigned",
|
||||
"assigned_group",
|
||||
"unassigned_group",
|
||||
"reassigned_group",
|
||||
"assigned_to_post",
|
||||
"assigned_group_to_post",
|
||||
"unassigned_from_post",
|
||||
"unassigned_group_from_post",
|
||||
"details_change",
|
||||
"note_change",
|
||||
"status_change",
|
||||
].includes(actionCode);
|
||||
}
|
||||
|
||||
function customizePostMenu(api) {
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
import { getOwnerWithFallback } from "discourse/lib/get-owner";
|
||||
import getURL from "discourse/lib/get-url";
|
||||
|
||||
export function assignedToUserPath(assignedToUser) {
|
||||
const siteSettings = getOwnerWithFallback(this).lookup(
|
||||
"service:site-settings"
|
||||
);
|
||||
|
||||
return getURL(
|
||||
siteSettings.assigns_user_url_path.replace(
|
||||
"{username}",
|
||||
assignedToUser.username
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
export function assignedToGroupPath(assignedToGroup) {
|
||||
return getURL(`/g/${assignedToGroup.name}/assigned/everyone`);
|
||||
}
|
|
@ -17,136 +17,12 @@ describe "Assign | Assigning topics", type: :system do
|
|||
sign_in(admin)
|
||||
end
|
||||
|
||||
describe "with open topic" do
|
||||
it "can assign and unassign" do
|
||||
visit "/t/#{topic.id}"
|
||||
%w[enabled disabled].each do |value|
|
||||
before { SiteSetting.glimmer_post_stream_mode = value }
|
||||
|
||||
topic_page.click_assign_topic
|
||||
assign_modal.assignee = staff_user
|
||||
assign_modal.confirm
|
||||
|
||||
expect(assign_modal).to be_closed
|
||||
expect(topic_page).to have_assigned(user: staff_user, at_post: 2)
|
||||
expect(find("#topic .assigned-to")).to have_content(staff_user.username)
|
||||
|
||||
topic_page.click_unassign_topic
|
||||
|
||||
expect(topic_page).to have_unassigned(user: staff_user, at_post: 3)
|
||||
expect(page).to have_no_css("#topic .assigned-to")
|
||||
end
|
||||
|
||||
it "can submit form with shortcut from texatea" do
|
||||
visit "/t/#{topic.id}"
|
||||
|
||||
topic_page.click_assign_topic
|
||||
assign_modal.assignee = staff_user
|
||||
|
||||
find("body").send_keys(:tab)
|
||||
find("body").send_keys(:control, :enter)
|
||||
|
||||
expect(assign_modal).to be_closed
|
||||
expect(topic_page).to have_assigned(user: staff_user, at_post: 2)
|
||||
expect(find("#topic .assigned-to")).to have_content(staff_user.username)
|
||||
end
|
||||
|
||||
context "when prioritize_full_name_in_ux setting is enabled" do
|
||||
before { SiteSetting.prioritize_full_name_in_ux = true }
|
||||
|
||||
it "shows the user's name after assign" do
|
||||
visit "/t/#{topic.id}"
|
||||
|
||||
topic_page.click_assign_topic
|
||||
assign_modal.assignee = staff_user
|
||||
assign_modal.confirm
|
||||
expect(find("#topic .assigned-to")).to have_content(staff_user.name)
|
||||
end
|
||||
|
||||
it "show the user's username if there is no name" do
|
||||
visit "/t/#{topic.id}"
|
||||
staff_user.name = nil
|
||||
staff_user.save
|
||||
staff_user.reload
|
||||
|
||||
topic_page.click_assign_topic
|
||||
assign_modal.assignee = staff_user
|
||||
assign_modal.confirm
|
||||
expect(find("#topic .assigned-to")).to have_content(staff_user.name)
|
||||
end
|
||||
end
|
||||
|
||||
context "when assigns are not public" do
|
||||
before { SiteSetting.assigns_public = false }
|
||||
|
||||
it "assigned small action post has 'private-assign' in class attribute" do
|
||||
visit "/t/#{topic.id}"
|
||||
|
||||
topic_page.click_assign_topic
|
||||
assign_modal.assignee = staff_user
|
||||
assign_modal.confirm
|
||||
|
||||
expect(assign_modal).to be_closed
|
||||
expect(topic_page).to have_assigned(
|
||||
user: staff_user,
|
||||
at_post: 2,
|
||||
class_attribute: ".private-assign",
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
context "when unassign_on_close is set to true" do
|
||||
before { SiteSetting.unassign_on_close = true }
|
||||
|
||||
it "unassigns the topic on close" do
|
||||
visit "/t/#{topic.id}"
|
||||
|
||||
topic_page.click_assign_topic
|
||||
assign_modal.assignee = staff_user
|
||||
assign_modal.confirm
|
||||
|
||||
expect(assign_modal).to be_closed
|
||||
expect(topic_page).to have_assigned(user: staff_user, at_post: 2)
|
||||
|
||||
find(".timeline-controls .toggle-admin-menu").click
|
||||
find(".topic-admin-close").click
|
||||
|
||||
expect(find("#post_3")).to have_content(
|
||||
I18n.t("js.action_codes.closed.enabled", when: "just now"),
|
||||
)
|
||||
expect(page).to have_no_css("#post_4")
|
||||
expect(page).to have_no_css("#topic .assigned-to")
|
||||
end
|
||||
|
||||
it "can assign the previous assignee" do
|
||||
visit "/t/#{topic.id}"
|
||||
|
||||
topic_page.click_assign_topic
|
||||
assign_modal.assignee = staff_user
|
||||
assign_modal.confirm
|
||||
|
||||
expect(assign_modal).to be_closed
|
||||
expect(topic_page).to have_assigned(user: staff_user, at_post: 2)
|
||||
|
||||
find(".timeline-controls .toggle-admin-menu").click
|
||||
find(".topic-admin-close").click
|
||||
|
||||
expect(find("#post_3")).to have_content(
|
||||
I18n.t("js.action_codes.closed.enabled", when: "just now"),
|
||||
)
|
||||
expect(page).to have_no_css("#post_4")
|
||||
expect(page).to have_no_css("#topic .assigned-to")
|
||||
|
||||
topic_page.click_assign_topic
|
||||
assign_modal.assignee = staff_user
|
||||
assign_modal.confirm
|
||||
|
||||
expect(page).to have_no_css("#post_4")
|
||||
expect(find("#topic .assigned-to")).to have_content(staff_user.username)
|
||||
end
|
||||
|
||||
context "when reassign_on_open is set to true" do
|
||||
before { SiteSetting.reassign_on_open = true }
|
||||
|
||||
it "reassigns the topic on open" do
|
||||
context "when glimmer_post_stream_mode=#{value}" do
|
||||
describe "with open topic" do
|
||||
it "can assign and unassign" do
|
||||
visit "/t/#{topic.id}"
|
||||
|
||||
topic_page.click_assign_topic
|
||||
|
@ -155,24 +31,154 @@ describe "Assign | Assigning topics", type: :system do
|
|||
|
||||
expect(assign_modal).to be_closed
|
||||
expect(topic_page).to have_assigned(user: staff_user, at_post: 2)
|
||||
|
||||
find(".timeline-controls .toggle-admin-menu").click
|
||||
find(".topic-admin-close").click
|
||||
|
||||
expect(find("#post_3")).to have_content(
|
||||
I18n.t("js.action_codes.closed.enabled", when: "just now"),
|
||||
)
|
||||
expect(page).to have_no_css("#post_4")
|
||||
expect(page).to have_no_css("#topic .assigned-to")
|
||||
|
||||
find(".timeline-controls .toggle-admin-menu").click
|
||||
find(".topic-admin-open").click
|
||||
|
||||
expect(find("#post_4")).to have_content(
|
||||
I18n.t("js.action_codes.closed.disabled", when: "just now"),
|
||||
)
|
||||
expect(page).to have_no_css("#post_5")
|
||||
expect(find("#topic .assigned-to")).to have_content(staff_user.username)
|
||||
|
||||
topic_page.click_unassign_topic
|
||||
|
||||
expect(topic_page).to have_unassigned(user: staff_user, at_post: 3)
|
||||
expect(page).to have_no_css("#topic .assigned-to")
|
||||
end
|
||||
|
||||
it "can submit form with shortcut from texatea" do
|
||||
visit "/t/#{topic.id}"
|
||||
|
||||
topic_page.click_assign_topic
|
||||
assign_modal.assignee = staff_user
|
||||
|
||||
find("body").send_keys(:tab)
|
||||
find("body").send_keys(:control, :enter)
|
||||
|
||||
expect(assign_modal).to be_closed
|
||||
expect(topic_page).to have_assigned(user: staff_user, at_post: 2)
|
||||
expect(find("#topic .assigned-to")).to have_content(staff_user.username)
|
||||
end
|
||||
|
||||
context "when prioritize_full_name_in_ux setting is enabled" do
|
||||
before { SiteSetting.prioritize_full_name_in_ux = true }
|
||||
|
||||
it "shows the user's name after assign" do
|
||||
visit "/t/#{topic.id}"
|
||||
|
||||
topic_page.click_assign_topic
|
||||
assign_modal.assignee = staff_user
|
||||
assign_modal.confirm
|
||||
expect(find("#topic .assigned-to")).to have_content(staff_user.name)
|
||||
end
|
||||
|
||||
it "show the user's username if there is no name" do
|
||||
visit "/t/#{topic.id}"
|
||||
staff_user.name = nil
|
||||
staff_user.save
|
||||
staff_user.reload
|
||||
|
||||
topic_page.click_assign_topic
|
||||
assign_modal.assignee = staff_user
|
||||
assign_modal.confirm
|
||||
expect(find("#topic .assigned-to")).to have_content(staff_user.name)
|
||||
end
|
||||
end
|
||||
|
||||
context "when assigns are not public" do
|
||||
before { SiteSetting.assigns_public = false }
|
||||
|
||||
it "assigned small action post has 'private-assign' in class attribute" do
|
||||
visit "/t/#{topic.id}"
|
||||
|
||||
topic_page.click_assign_topic
|
||||
assign_modal.assignee = staff_user
|
||||
assign_modal.confirm
|
||||
|
||||
expect(assign_modal).to be_closed
|
||||
expect(topic_page).to have_assigned(
|
||||
user: staff_user,
|
||||
at_post: 2,
|
||||
class_attribute: ".private-assign",
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
context "when unassign_on_close is set to true" do
|
||||
before { SiteSetting.unassign_on_close = true }
|
||||
|
||||
it "unassigns the topic on close" do
|
||||
visit "/t/#{topic.id}"
|
||||
|
||||
topic_page.click_assign_topic
|
||||
assign_modal.assignee = staff_user
|
||||
assign_modal.confirm
|
||||
|
||||
expect(assign_modal).to be_closed
|
||||
expect(topic_page).to have_assigned(user: staff_user, at_post: 2)
|
||||
|
||||
find(".timeline-controls .toggle-admin-menu").click
|
||||
find(".topic-admin-close").click
|
||||
|
||||
expect(find("#post_3")).to have_content(
|
||||
I18n.t("js.action_codes.closed.enabled", when: "just now"),
|
||||
)
|
||||
expect(page).to have_no_css("#post_4")
|
||||
expect(page).to have_no_css("#topic .assigned-to")
|
||||
end
|
||||
|
||||
it "can assign the previous assignee" do
|
||||
visit "/t/#{topic.id}"
|
||||
|
||||
topic_page.click_assign_topic
|
||||
assign_modal.assignee = staff_user
|
||||
assign_modal.confirm
|
||||
|
||||
expect(assign_modal).to be_closed
|
||||
expect(topic_page).to have_assigned(user: staff_user, at_post: 2)
|
||||
|
||||
find(".timeline-controls .toggle-admin-menu").click
|
||||
find(".topic-admin-close").click
|
||||
|
||||
expect(find("#post_3")).to have_content(
|
||||
I18n.t("js.action_codes.closed.enabled", when: "just now"),
|
||||
)
|
||||
expect(page).to have_no_css("#post_4")
|
||||
expect(page).to have_no_css("#topic .assigned-to")
|
||||
|
||||
topic_page.click_assign_topic
|
||||
assign_modal.assignee = staff_user
|
||||
assign_modal.confirm
|
||||
|
||||
expect(page).to have_no_css("#post_4")
|
||||
expect(find("#topic .assigned-to")).to have_content(staff_user.username)
|
||||
end
|
||||
|
||||
context "when reassign_on_open is set to true" do
|
||||
before { SiteSetting.reassign_on_open = true }
|
||||
|
||||
it "reassigns the topic on open" do
|
||||
visit "/t/#{topic.id}"
|
||||
|
||||
topic_page.click_assign_topic
|
||||
assign_modal.assignee = staff_user
|
||||
assign_modal.confirm
|
||||
|
||||
expect(assign_modal).to be_closed
|
||||
expect(topic_page).to have_assigned(user: staff_user, at_post: 2)
|
||||
|
||||
find(".timeline-controls .toggle-admin-menu").click
|
||||
find(".topic-admin-close").click
|
||||
|
||||
expect(find("#post_3")).to have_content(
|
||||
I18n.t("js.action_codes.closed.enabled", when: "just now"),
|
||||
)
|
||||
expect(page).to have_no_css("#post_4")
|
||||
expect(page).to have_no_css("#topic .assigned-to")
|
||||
|
||||
find(".timeline-controls .toggle-admin-menu").click
|
||||
find(".topic-admin-open").click
|
||||
|
||||
expect(find("#post_4")).to have_content(
|
||||
I18n.t("js.action_codes.closed.disabled", when: "just now"),
|
||||
)
|
||||
expect(page).to have_no_css("#post_5")
|
||||
expect(find("#topic .assigned-to")).to have_content(staff_user.username)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -2,13 +2,21 @@ import { visit } from "@ember/test-helpers";
|
|||
import { test } from "qunit";
|
||||
import { acceptance } from "discourse/tests/helpers/qunit-helpers";
|
||||
|
||||
acceptance("Discourse Assign | Assign disabled mobile", function (needs) {
|
||||
needs.user({ can_assign: true });
|
||||
needs.mobileView();
|
||||
needs.settings({ assign_enabled: false });
|
||||
["enabled", "disabled"].forEach((postStreamMode) => {
|
||||
acceptance(
|
||||
`Discourse Assign | Assign disabled mobile (glimmer_post_stream_mode = ${postStreamMode})`,
|
||||
function (needs) {
|
||||
needs.user({ can_assign: true });
|
||||
needs.mobileView();
|
||||
needs.settings({
|
||||
assign_enabled: false,
|
||||
glimmer_post_stream_mode: postStreamMode,
|
||||
});
|
||||
|
||||
test("Footer dropdown does not contain button", async function (assert) {
|
||||
await visit("/t/internationalization-localization/280");
|
||||
assert.dom(".assign").doesNotExist();
|
||||
});
|
||||
test("Footer dropdown does not contain button", async function (assert) {
|
||||
await visit("/t/internationalization-localization/280");
|
||||
assert.dom(".assign").doesNotExist();
|
||||
});
|
||||
}
|
||||
);
|
||||
});
|
||||
|
|
|
@ -45,175 +45,191 @@ acceptance("Discourse Assign | Assign mobile", function (needs) {
|
|||
});
|
||||
});
|
||||
|
||||
acceptance("Discourse Assign | Assign desktop", function (needs) {
|
||||
needs.user({ can_assign: true });
|
||||
needs.settings({ assign_enabled: true });
|
||||
|
||||
needs.pretender((server, helper) => {
|
||||
server.get("/assign/suggestions", () => {
|
||||
return helper.response({
|
||||
success: true,
|
||||
assign_allowed_groups: false,
|
||||
assign_allowed_for_groups: [],
|
||||
suggestions: [
|
||||
{
|
||||
id: 19,
|
||||
username: "eviltrout",
|
||||
name: "Robin Ward",
|
||||
avatar_template:
|
||||
"/user_avatar/meta.discourse.org/eviltrout/{size}/5275_2.png",
|
||||
},
|
||||
],
|
||||
["enabled", "disabled"].forEach((postStreamMode) => {
|
||||
acceptance(
|
||||
`Discourse Assign | Assign desktop (glimmer_post_stream_mode = ${postStreamMode})`,
|
||||
function (needs) {
|
||||
needs.user({ can_assign: true });
|
||||
needs.settings({
|
||||
assign_enabled: true,
|
||||
glimmer_post_stream_mode: postStreamMode,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test("Assigning user to a post", async function (assert) {
|
||||
await visit("/t/internationalization-localization/280");
|
||||
|
||||
assert
|
||||
.dom("#post_2 .post-action-menu__assign-post")
|
||||
.doesNotExist("assign to post button is hidden");
|
||||
|
||||
await click("#post_2 button.show-more-actions");
|
||||
assert
|
||||
.dom("#post_2 .post-action-menu__assign-post")
|
||||
.exists("assign to post button exists");
|
||||
|
||||
await click("#post_2 .post-action-menu__assign-post");
|
||||
assert.dom(".assign.d-modal").exists("assign modal opens");
|
||||
|
||||
const menu = selectKit(".assign.d-modal .user-chooser");
|
||||
assert.true(menu.isExpanded(), "user selector is expanded");
|
||||
|
||||
await click(".assign.d-modal .btn-primary");
|
||||
assert.dom(".error-label").includesText("Choose a user to assign");
|
||||
|
||||
await menu.expand();
|
||||
await menu.selectRowByIndex(0);
|
||||
assert.strictEqual(menu.header().value(), "eviltrout");
|
||||
assert.dom(".error-label").doesNotExist();
|
||||
|
||||
pretender.put("/assign/assign", ({ requestBody }) => {
|
||||
const body = parsePostData(requestBody);
|
||||
assert.strictEqual(body.target_type, "Post");
|
||||
assert.strictEqual(body.username, "eviltrout");
|
||||
assert.strictEqual(body.note, "a note!");
|
||||
return response({ success: true });
|
||||
});
|
||||
|
||||
await fillIn("#assign-modal-note", "a note!");
|
||||
await click(".assign.d-modal .btn-primary");
|
||||
|
||||
assert.dom(".assign.d-modal").doesNotExist("assign modal closes");
|
||||
});
|
||||
|
||||
test("Footer dropdown contains button", async function (assert) {
|
||||
await visit("/t/internationalization-localization/280");
|
||||
await click("#topic-footer-button-assign");
|
||||
|
||||
assert.dom(".assign.d-modal").exists("assign modal opens");
|
||||
});
|
||||
});
|
||||
|
||||
acceptance("Discourse Assign | Assign Status enabled", function (needs) {
|
||||
needs.user({
|
||||
can_assign: true,
|
||||
});
|
||||
needs.settings({
|
||||
assign_enabled: true,
|
||||
enable_assign_status: true,
|
||||
assign_statuses: "New|In Progress|Done",
|
||||
});
|
||||
|
||||
needs.pretender((server, helper) => {
|
||||
server.get("/assign/suggestions", () => {
|
||||
return helper.response({
|
||||
success: true,
|
||||
assign_allowed_groups: false,
|
||||
assign_allowed_for_groups: [],
|
||||
suggestions: [
|
||||
{
|
||||
id: 19,
|
||||
username: "eviltrout",
|
||||
name: "Robin Ward",
|
||||
avatar_template:
|
||||
"/user_avatar/meta.discourse.org/eviltrout/{size}/5275_2.png",
|
||||
},
|
||||
],
|
||||
needs.pretender((server, helper) => {
|
||||
server.get("/assign/suggestions", () => {
|
||||
return helper.response({
|
||||
success: true,
|
||||
assign_allowed_groups: false,
|
||||
assign_allowed_for_groups: [],
|
||||
suggestions: [
|
||||
{
|
||||
id: 19,
|
||||
username: "eviltrout",
|
||||
name: "Robin Ward",
|
||||
avatar_template:
|
||||
"/user_avatar/meta.discourse.org/eviltrout/{size}/5275_2.png",
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
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");
|
||||
test("Assigning user to a post", async function (assert) {
|
||||
await visit("/t/internationalization-localization/280");
|
||||
|
||||
return response({ success: true });
|
||||
});
|
||||
assert
|
||||
.dom("#post_2 .post-action-menu__assign-post")
|
||||
.doesNotExist("assign to post button is hidden");
|
||||
|
||||
await visit("/t/internationalization-localization/280");
|
||||
await click("#topic-footer-button-assign");
|
||||
await click("#post_2 button.show-more-actions");
|
||||
assert
|
||||
.dom("#post_2 .post-action-menu__assign-post")
|
||||
.exists("assign to post button exists");
|
||||
|
||||
assert
|
||||
.dom(".assign.d-modal #assign-status")
|
||||
.exists("assign status dropdown exists");
|
||||
await click("#post_2 .post-action-menu__assign-post");
|
||||
assert.dom(".assign.d-modal").exists("assign modal opens");
|
||||
|
||||
const statusDropdown = selectKit("#assign-status");
|
||||
assert.strictEqual(statusDropdown.header().value(), "New");
|
||||
const menu = selectKit(".assign.d-modal .user-chooser");
|
||||
assert.true(menu.isExpanded(), "user selector is expanded");
|
||||
|
||||
await statusDropdown.expand();
|
||||
await statusDropdown.selectRowByValue("In Progress");
|
||||
assert.strictEqual(statusDropdown.header().value(), "In Progress");
|
||||
await click(".assign.d-modal .btn-primary");
|
||||
assert.dom(".error-label").includesText("Choose a user to assign");
|
||||
|
||||
const menu = selectKit(".assign.d-modal .user-chooser");
|
||||
await menu.expand();
|
||||
await menu.selectRowByIndex(0);
|
||||
await menu.expand();
|
||||
await menu.selectRowByIndex(0);
|
||||
assert.strictEqual(menu.header().value(), "eviltrout");
|
||||
assert.dom(".error-label").doesNotExist();
|
||||
|
||||
await click(".assign.d-modal .btn-primary");
|
||||
});
|
||||
});
|
||||
pretender.put("/assign/assign", ({ requestBody }) => {
|
||||
const body = parsePostData(requestBody);
|
||||
assert.strictEqual(body.target_type, "Post");
|
||||
assert.strictEqual(body.username, "eviltrout");
|
||||
assert.strictEqual(body.note, "a note!");
|
||||
return response({ success: true });
|
||||
});
|
||||
|
||||
acceptance("Discourse Assign | Assign Status disabled", function (needs) {
|
||||
needs.user({
|
||||
can_assign: true,
|
||||
});
|
||||
needs.settings({
|
||||
assign_enabled: true,
|
||||
enable_assign_status: false,
|
||||
});
|
||||
await fillIn("#assign-modal-note", "a note!");
|
||||
await click(".assign.d-modal .btn-primary");
|
||||
|
||||
needs.pretender((server, helper) => {
|
||||
server.get("/assign/suggestions", () => {
|
||||
return helper.response({
|
||||
success: true,
|
||||
assign_allowed_groups: false,
|
||||
assign_allowed_for_groups: [],
|
||||
suggestions: [
|
||||
{
|
||||
id: 19,
|
||||
username: "eviltrout",
|
||||
name: "Robin Ward",
|
||||
avatar_template:
|
||||
"/user_avatar/meta.discourse.org/eviltrout/{size}/5275_2.png",
|
||||
},
|
||||
],
|
||||
assert.dom(".assign.d-modal").doesNotExist("assign modal closes");
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test("Modal contains status dropdown", async function (assert) {
|
||||
await visit("/t/internationalization-localization/280");
|
||||
await click("#topic-footer-button-assign");
|
||||
test("Footer dropdown contains button", async function (assert) {
|
||||
await visit("/t/internationalization-localization/280");
|
||||
await click("#topic-footer-button-assign");
|
||||
|
||||
assert
|
||||
.dom(".assign.d-modal #assign-status")
|
||||
.doesNotExist("assign status dropdown doesn't exists");
|
||||
});
|
||||
assert.dom(".assign.d-modal").exists("assign modal opens");
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
acceptance(
|
||||
`Discourse Assign | Assign Status enabled (glimmer_post_stream_mode = ${postStreamMode})`,
|
||||
function (needs) {
|
||||
needs.user({
|
||||
can_assign: true,
|
||||
});
|
||||
needs.settings({
|
||||
assign_enabled: true,
|
||||
enable_assign_status: true,
|
||||
assign_statuses: "New|In Progress|Done",
|
||||
glimmer_post_stream_mode: postStreamMode,
|
||||
});
|
||||
|
||||
needs.pretender((server, helper) => {
|
||||
server.get("/assign/suggestions", () => {
|
||||
return helper.response({
|
||||
success: true,
|
||||
assign_allowed_groups: false,
|
||||
assign_allowed_for_groups: [],
|
||||
suggestions: [
|
||||
{
|
||||
id: 19,
|
||||
username: "eviltrout",
|
||||
name: "Robin Ward",
|
||||
avatar_template:
|
||||
"/user_avatar/meta.discourse.org/eviltrout/{size}/5275_2.png",
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
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 click("#topic-footer-button-assign");
|
||||
|
||||
assert
|
||||
.dom(".assign.d-modal #assign-status")
|
||||
.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");
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
acceptance(
|
||||
`Discourse Assign | Assign Status disabled (glimmer_post_stream_mode = ${postStreamMode})`,
|
||||
function (needs) {
|
||||
needs.user({
|
||||
can_assign: true,
|
||||
});
|
||||
needs.settings({
|
||||
assign_enabled: true,
|
||||
enable_assign_status: false,
|
||||
glimmer_post_stream_mode: postStreamMode,
|
||||
});
|
||||
|
||||
needs.pretender((server, helper) => {
|
||||
server.get("/assign/suggestions", () => {
|
||||
return helper.response({
|
||||
success: true,
|
||||
assign_allowed_groups: false,
|
||||
assign_allowed_for_groups: [],
|
||||
suggestions: [
|
||||
{
|
||||
id: 19,
|
||||
username: "eviltrout",
|
||||
name: "Robin Ward",
|
||||
avatar_template:
|
||||
"/user_avatar/meta.discourse.org/eviltrout/{size}/5275_2.png",
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test("Modal contains status dropdown", async function (assert) {
|
||||
await visit("/t/internationalization-localization/280");
|
||||
await click("#topic-footer-button-assign");
|
||||
|
||||
assert
|
||||
.dom(".assign.d-modal #assign-status")
|
||||
.doesNotExist("assign status dropdown doesn't exists");
|
||||
});
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
// See RemindAssignsFrequencySiteSettings
|
||||
|
|
|
@ -82,171 +82,197 @@ function assignNewUserToTopic(needs) {
|
|||
});
|
||||
}
|
||||
|
||||
acceptance("Discourse Assign | Assigned topic", function (needs) {
|
||||
needs.user();
|
||||
needs.settings({
|
||||
assign_enabled: true,
|
||||
tagging_enabled: true,
|
||||
assigns_user_url_path: "/",
|
||||
assigns_public: true,
|
||||
enable_assign_status: true,
|
||||
});
|
||||
["enabled", "disabled"].forEach((postStreamMode) => {
|
||||
acceptance(
|
||||
`Discourse Assign | Assigned topic (glimmer_post_stream_mode = ${postStreamMode})`,
|
||||
function (needs) {
|
||||
needs.user();
|
||||
needs.settings({
|
||||
assign_enabled: true,
|
||||
tagging_enabled: true,
|
||||
assigns_user_url_path: "/",
|
||||
assigns_public: true,
|
||||
enable_assign_status: true,
|
||||
glimmer_post_stream_mode: postStreamMode,
|
||||
});
|
||||
|
||||
assignCurrentUserToTopic(needs);
|
||||
assignCurrentUserToTopic(needs);
|
||||
|
||||
test("Shows user assignment info", async function (assert) {
|
||||
updateCurrentUser({ can_assign: true });
|
||||
await visit("/t/assignment-topic/44");
|
||||
test("Shows user assignment info", async function (assert) {
|
||||
updateCurrentUser({ can_assign: true });
|
||||
await visit("/t/assignment-topic/44");
|
||||
|
||||
assert
|
||||
.dom("#topic-title .assigned-to")
|
||||
.hasText("eviltrout", "shows assignment in the header");
|
||||
assert
|
||||
.dom("#post_1 .assigned-to")
|
||||
.hasText(
|
||||
"Assigned topic to eviltrout#2 to Developers",
|
||||
"shows assignment and indirect assignments in the first post"
|
||||
);
|
||||
assert.dom("#post_1 .assigned-to svg.d-icon-user-plus").exists();
|
||||
assert.dom("#post_1 .assigned-to a[href='/']").exists();
|
||||
assert
|
||||
.dom(".discourse-tags .assigned-to[href='/t/28830'] span")
|
||||
.hasAttribute("title", "Shark Doododooo", "shows topic assign notes");
|
||||
assert
|
||||
.dom(".discourse-tags .assigned-to[href='/p/2'] span")
|
||||
.hasAttribute(
|
||||
"title",
|
||||
'<script>alert("xss")</script>',
|
||||
"shows indirect assign notes"
|
||||
);
|
||||
assert
|
||||
.dom("#topic-footer-dropdown-reassign")
|
||||
.exists("shows reassign dropdown at the bottom of the topic");
|
||||
});
|
||||
assert
|
||||
.dom("#topic-title .assigned-to")
|
||||
.hasText("eviltrout", "shows assignment in the header");
|
||||
|
||||
test("Shows group assignment info", async function (assert) {
|
||||
updateCurrentUser({ can_assign: true });
|
||||
await visit("/t/assignment-topic/45");
|
||||
assert
|
||||
.dom("#post_1 .assigned-to")
|
||||
.includesText(
|
||||
"Assigned topic to eviltrout",
|
||||
"shows assignment in the first post"
|
||||
);
|
||||
assert
|
||||
.dom("#post_1 .assigned-to")
|
||||
.includesText("#2 to Developers", "Also shows indirects assignments");
|
||||
assert.dom("#post_1 .assigned-to svg.d-icon-user-plus").exists();
|
||||
assert.dom("#post_1 .assigned-to a[href='/']").exists();
|
||||
assert
|
||||
.dom(".discourse-tags .assigned-to[href='/t/28830'] span")
|
||||
.hasAttribute("title", "Shark Doododooo", "shows topic assign notes");
|
||||
assert
|
||||
.dom(".discourse-tags .assigned-to[href='/p/2'] span")
|
||||
.hasAttribute(
|
||||
"title",
|
||||
'<script>alert("xss")</script>',
|
||||
"shows indirect assign notes"
|
||||
);
|
||||
assert
|
||||
.dom("#topic-footer-dropdown-reassign")
|
||||
.exists("shows reassign dropdown at the bottom of the topic");
|
||||
});
|
||||
|
||||
assert
|
||||
.dom("#topic-title .assigned-to")
|
||||
.hasText("Developers", "shows assignment in the header");
|
||||
assert
|
||||
.dom("#post_1 .assigned-to--group")
|
||||
.hasText(
|
||||
"Assigned topic to Developers",
|
||||
"shows assignment in the first post"
|
||||
);
|
||||
assert.dom("#post_1 .assigned-to svg.d-icon-group-plus").exists();
|
||||
assert
|
||||
.dom("#post_1 .assigned-to a[href='/g/Developers/assigned/everyone']")
|
||||
.exists();
|
||||
assert
|
||||
.dom("#topic-footer-dropdown-reassign")
|
||||
.exists("shows reassign dropdown at the bottom of the topic");
|
||||
});
|
||||
test("Shows group assignment info", async function (assert) {
|
||||
updateCurrentUser({ can_assign: true });
|
||||
await visit("/t/assignment-topic/45");
|
||||
|
||||
test("User without assign ability cannot see footer button", async function (assert) {
|
||||
updateCurrentUser({ can_assign: false, admin: false, moderator: false });
|
||||
await visit("/t/assignment-topic/45");
|
||||
assert
|
||||
.dom("#topic-title .assigned-to")
|
||||
.hasText("Developers", "shows assignment in the header");
|
||||
assert
|
||||
.dom("#post_1 .assigned-to--group")
|
||||
.hasText(
|
||||
"Assigned topic to Developers",
|
||||
"shows assignment in the first post"
|
||||
);
|
||||
assert.dom("#post_1 .assigned-to svg.d-icon-group-plus").exists();
|
||||
assert
|
||||
.dom("#post_1 .assigned-to a[href='/g/Developers/assigned/everyone']")
|
||||
.exists();
|
||||
assert
|
||||
.dom("#topic-footer-dropdown-reassign")
|
||||
.exists("shows reassign dropdown at the bottom of the topic");
|
||||
});
|
||||
|
||||
assert
|
||||
.dom("#topic-footer-dropdown-reassign")
|
||||
.doesNotExist(
|
||||
"does not show reassign dropdown at the bottom of the topic"
|
||||
);
|
||||
});
|
||||
test("User without assign ability cannot see footer button", async function (assert) {
|
||||
updateCurrentUser({
|
||||
can_assign: false,
|
||||
admin: false,
|
||||
moderator: false,
|
||||
});
|
||||
await visit("/t/assignment-topic/45");
|
||||
|
||||
test("Shows assignment notification", async function (assert) {
|
||||
updateCurrentUser({ can_assign: true });
|
||||
assert
|
||||
.dom("#topic-footer-dropdown-reassign")
|
||||
.doesNotExist(
|
||||
"does not show reassign dropdown at the bottom of the topic"
|
||||
);
|
||||
});
|
||||
|
||||
await visit("/u/eviltrout/notifications");
|
||||
test("Shows assignment notification", async function (assert) {
|
||||
updateCurrentUser({ can_assign: true });
|
||||
|
||||
const notification = query(
|
||||
"section.user-content .user-notifications-list li.notification"
|
||||
);
|
||||
await visit("/u/eviltrout/notifications");
|
||||
|
||||
assert.true(
|
||||
notification.classList.contains("assigned"),
|
||||
"with correct assigned class"
|
||||
);
|
||||
const notification = query(
|
||||
"section.user-content .user-notifications-list li.notification"
|
||||
);
|
||||
|
||||
assert.strictEqual(
|
||||
notification.querySelector("a").title,
|
||||
i18n("notifications.titles.assigned"),
|
||||
"with correct title"
|
||||
);
|
||||
assert.strictEqual(
|
||||
notification.querySelector("svg use").href["baseVal"],
|
||||
"#user-plus",
|
||||
"with correct icon"
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
acceptance("Discourse Assign | Reassign topic", function (needs) {
|
||||
needs.user();
|
||||
needs.settings({
|
||||
assign_enabled: true,
|
||||
tagging_enabled: true,
|
||||
assigns_user_url_path: "/",
|
||||
});
|
||||
|
||||
assignNewUserToTopic(needs);
|
||||
|
||||
test("Reassign Footer dropdown contains reassign buttons", async function (assert) {
|
||||
updateCurrentUser({ can_assign: true });
|
||||
const menu = selectKit("#topic-footer-dropdown-reassign");
|
||||
|
||||
await visit("/t/assignment-topic/44");
|
||||
await menu.expand();
|
||||
|
||||
assert.true(menu.rowByValue("unassign").exists());
|
||||
assert.true(menu.rowByValue("reassign").exists());
|
||||
assert.true(menu.rowByValue("reassign-self").exists());
|
||||
});
|
||||
});
|
||||
|
||||
acceptance("Discourse Assign | Reassign topic | mobile", function (needs) {
|
||||
needs.user();
|
||||
needs.mobileView();
|
||||
needs.settings({
|
||||
assign_enabled: true,
|
||||
tagging_enabled: true,
|
||||
assigns_user_url_path: "/",
|
||||
});
|
||||
|
||||
assignNewUserToTopic(needs);
|
||||
|
||||
test("Mobile Footer dropdown contains reassign buttons", async function (assert) {
|
||||
updateCurrentUser({ can_assign: true });
|
||||
|
||||
await visit("/t/assignment-topic/44");
|
||||
await click(".topic-footer-mobile-dropdown-trigger");
|
||||
|
||||
assert.dom("#topic-footer-button-unassign-mobile").exists();
|
||||
assert.dom("#topic-footer-button-reassign-self-mobile").exists();
|
||||
assert.dom("#topic-footer-button-reassign-mobile").exists();
|
||||
});
|
||||
});
|
||||
|
||||
acceptance("Discourse Assign | Reassign topic conditionals", function (needs) {
|
||||
needs.user();
|
||||
needs.settings({
|
||||
assign_enabled: true,
|
||||
tagging_enabled: true,
|
||||
assigns_user_url_path: "/",
|
||||
});
|
||||
|
||||
assignCurrentUserToTopic(needs);
|
||||
|
||||
test("Reassign Footer dropdown won't display reassign-to-self button when already assigned to current user", async function (assert) {
|
||||
updateCurrentUser({ can_assign: true });
|
||||
const menu = selectKit("#topic-footer-dropdown-reassign");
|
||||
|
||||
await visit("/t/assignment-topic/44");
|
||||
await menu.expand();
|
||||
|
||||
assert.false(menu.rowByValue("reassign-self").exists());
|
||||
});
|
||||
assert.true(
|
||||
notification.classList.contains("assigned"),
|
||||
"with correct assigned class"
|
||||
);
|
||||
|
||||
assert.strictEqual(
|
||||
notification.querySelector("a").title,
|
||||
i18n("notifications.titles.assigned"),
|
||||
"with correct title"
|
||||
);
|
||||
assert.strictEqual(
|
||||
notification.querySelector("svg use").href["baseVal"],
|
||||
"#user-plus",
|
||||
"with correct icon"
|
||||
);
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
acceptance(
|
||||
`Discourse Assign | Reassign topic (glimmer_post_stream_mode = ${postStreamMode})`,
|
||||
function (needs) {
|
||||
needs.user();
|
||||
needs.settings({
|
||||
assign_enabled: true,
|
||||
tagging_enabled: true,
|
||||
assigns_user_url_path: "/",
|
||||
glimmer_post_stream_mode: postStreamMode,
|
||||
});
|
||||
|
||||
assignNewUserToTopic(needs);
|
||||
|
||||
test("Reassign Footer dropdown contains reassign buttons", async function (assert) {
|
||||
updateCurrentUser({ can_assign: true });
|
||||
const menu = selectKit("#topic-footer-dropdown-reassign");
|
||||
|
||||
await visit("/t/assignment-topic/44");
|
||||
await menu.expand();
|
||||
|
||||
assert.true(menu.rowByValue("unassign").exists());
|
||||
assert.true(menu.rowByValue("reassign").exists());
|
||||
assert.true(menu.rowByValue("reassign-self").exists());
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
acceptance(
|
||||
`Discourse Assign | Reassign topic | mobile (glimmer_post_stream_mode = ${postStreamMode})`,
|
||||
function (needs) {
|
||||
needs.user();
|
||||
needs.mobileView();
|
||||
needs.settings({
|
||||
assign_enabled: true,
|
||||
tagging_enabled: true,
|
||||
assigns_user_url_path: "/",
|
||||
glimmer_post_stream_mode: postStreamMode,
|
||||
});
|
||||
|
||||
assignNewUserToTopic(needs);
|
||||
|
||||
test("Mobile Footer dropdown contains reassign buttons", async function (assert) {
|
||||
updateCurrentUser({ can_assign: true });
|
||||
|
||||
await visit("/t/assignment-topic/44");
|
||||
await click(".topic-footer-mobile-dropdown-trigger");
|
||||
|
||||
assert.dom("#topic-footer-button-unassign-mobile").exists();
|
||||
assert.dom("#topic-footer-button-reassign-self-mobile").exists();
|
||||
assert.dom("#topic-footer-button-reassign-mobile").exists();
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
acceptance(
|
||||
`Discourse Assign | Reassign topic conditionals (glimmer_post_stream_mode = ${postStreamMode})`,
|
||||
function (needs) {
|
||||
needs.user();
|
||||
needs.settings({
|
||||
assign_enabled: true,
|
||||
tagging_enabled: true,
|
||||
assigns_user_url_path: "/",
|
||||
glimmer_post_stream_mode: postStreamMode,
|
||||
});
|
||||
|
||||
assignCurrentUserToTopic(needs);
|
||||
|
||||
test("Reassign Footer dropdown won't display reassign-to-self button when already assigned to current user", async function (assert) {
|
||||
updateCurrentUser({ can_assign: true });
|
||||
const menu = selectKit("#topic-footer-dropdown-reassign");
|
||||
|
||||
await visit("/t/assignment-topic/44");
|
||||
await menu.expand();
|
||||
|
||||
assert.false(menu.rowByValue("reassign-self").exists());
|
||||
});
|
||||
}
|
||||
);
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue