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

330 lines
8.9 KiB
JavaScript

import { renderAvatar } from "discourse/helpers/user-avatar";
import { withPluginApi } from "discourse/lib/plugin-api";
import { default as computed } from "discourse-common/utils/decorators";
import { iconNode } from "discourse-common/lib/icon-library";
import { h } from "virtual-dom";
import { iconHTML } from "discourse-common/lib/icon-library";
import { queryRegistry } from "discourse/widgets/widget";
import { getOwner } from "discourse-common/lib/get-owner";
import { htmlSafe } from "@ember/template";
function titleForState(user) {
if (user) {
return I18n.t("discourse_assign.unassign.help", {
username: user.username
});
} else {
return I18n.t("discourse_assign.assign.help");
}
}
function registerTopicFooterButtons(api) {
api.registerTopicFooterButton({
id: "assign",
icon() {
const hasAssignement = this.get("topic.assigned_to_user");
return hasAssignement
? this.site.mobileView
? "user-times"
: null
: "user-plus";
},
priority: 250,
translatedTitle() {
return titleForState(this.get("topic.assigned_to_user"));
},
translatedAriaLabel() {
return titleForState(this.get("topic.assigned_to_user"));
},
translatedLabel() {
const user = this.get("topic.assigned_to_user");
if (user) {
const label = I18n.t("discourse_assign.unassign.title");
if (this.site.mobileView) {
return htmlSafe(
`<span class="unassign-label"><span class="text">${label}</span><span class="username">${
user.username
}</span></span>${renderAvatar(user, {
imageSize: "small",
ignoreTitle: true
})}`
);
} else {
return htmlSafe(
`${renderAvatar(user, {
imageSize: "tiny",
ignoreTitle: true
})}<span class="unassign-label">${label}</span>`
);
}
} else {
return I18n.t("discourse_assign.assign.title");
}
},
action() {
if (!this.get("currentUser.can_assign")) {
return;
}
const taskActions = getOwner(this).lookup("service:task-actions");
const topic = this.topic;
const assignedUser = topic.get("assigned_to_user.username");
if (assignedUser) {
this.set("topic.assigned_to_user", null);
taskActions.unassign(topic.id);
} else {
taskActions.assign(topic);
}
},
dropdown() {
return this.site.mobileView && !this.get("topic.isPrivateMessage");
},
classNames: ["assign"],
dependentKeys: [
"topic.isPrivateMessage",
"topic.assigned_to_user",
"currentUser.can_assign",
"topic.assigned_to_user.username"
],
displayed() {
return this.currentUser && this.currentUser.can_assign;
}
});
}
function initialize(api) {
api.addNavigationBarItem({
name: "unassigned",
customFilter: category => {
return category && category.enable_unassigned_filter;
},
customHref: category => {
if (category) {
return (
Discourse.getURL(category.url) +
"/l/latest?status=open&assigned=nobody"
);
}
},
forceActive: (category, args, router) => {
const queryParams = router.currentRoute.queryParams;
return (
queryParams &&
Object.keys(queryParams).length === 2 &&
queryParams["assigned"] === "nobody" &&
queryParams["status"] === "open"
);
},
before: "top"
});
// You can't act on flags claimed by another user
api.modifyClass(
"component:flagged-post",
{
@computed("flaggedPost.topic.assigned_to_user_id")
canAct(assignedToUserId) {
let { siteSettings } = this;
if (siteSettings.assign_locks_flags) {
let unassigned = this.currentUser.id !== assignedToUserId;
// Can never act on another user's flags
if (assignedToUserId && unassigned) {
return false;
}
// If flags require assignment
if (this.siteSettings.flags_require_assign && unassigned) {
return false;
}
}
return this.actableFilter;
},
didInsertElement() {
this._super(...arguments);
this.messageBus.subscribe("/staff/topic-assignment", data => {
let flaggedPost = this.flaggedPost;
if (data.topic_id === flaggedPost.get("topic.id")) {
flaggedPost.set(
"topic.assigned_to_user_id",
data.type === "assigned" ? data.assigned_to.id : null
);
flaggedPost.set("topic.assigned_to_user", data.assigned_to);
}
});
},
willDestroyElement() {
this._super(...arguments);
this.messageBus.unsubscribe("/staff/topic-assignment");
}
},
{ ignoreMissing: true }
);
api.modifyClass("model:topic", {
@computed("assigned_to_user")
assignedToUserPath(assignedToUser) {
const siteSettings = api.container.lookup("site-settings:main");
return Discourse.getURL(
siteSettings.assigns_user_url_path.replace(
"{username}",
assignedToUser.username
)
);
}
});
api.modifyClass("model:bookmark", {
@computed("assigned_to_user")
assignedToUserPath(assignedToUser) {
return Discourse.getURL(
this.siteSettings.assigns_user_url_path.replace(
"{username}",
assignedToUser.username
)
);
}
});
api.addPostSmallActionIcon("assigned", "user-plus");
api.addPostSmallActionIcon("unassigned", "user-times");
api.addPostTransformCallback(transformed => {
if (
transformed.actionCode === "assigned" ||
transformed.actionCode === "unassigned"
) {
transformed.isSmallAction = true;
transformed.canEdit = false;
}
});
api.addDiscoveryQueryParam("assigned", { replace: true, refreshModel: true });
api.addTagsHtmlCallback(topic => {
const assignedTo = topic.get("assigned_to_user.username");
if (assignedTo) {
const assignedPath = topic.assignedToUserPath;
return `<a data-auto-route='true' class='assigned-to discourse-tag simple' href='${assignedPath}'>${iconHTML(
"user-plus"
)}${assignedTo}</a>`;
}
});
api.addUserMenuGlyph(widget => {
if (widget.currentUser && widget.currentUser.can_assign) {
const glyph = {
label: "discourse_assign.assigned",
className: "assigned",
icon: "user-plus",
href: `${widget.currentUser.path}/activity/assigned`
};
if (queryRegistry("quick-access-panel")) {
glyph["action"] = "quickAccess";
glyph["actionParam"] = "assignments";
}
return glyph;
}
});
api.createWidget("assigned-to", {
html(attrs) {
let { assignedToUser, href } = attrs;
return h("p.assigned-to", [
iconNode("user-plus"),
h("span.assign-text", I18n.t("discourse_assign.assigned_to")),
h(
"a",
{ attributes: { class: "assigned-to-username", href } },
assignedToUser.username
)
]);
}
});
api.modifyClass("controller:topic", {
subscribe() {
this._super(...arguments);
this.messageBus.subscribe("/staff/topic-assignment", data => {
const topic = this.model;
const topicId = topic.id;
if (data.topic_id === topicId) {
topic.set(
"assigned_to_user_id",
data.type === "assigned" ? data.assigned_to.id : null
);
topic.set("assigned_to_user", data.assigned_to);
}
this.appEvents.trigger("header:update-topic", topic);
});
},
unsubscribe() {
this._super(...arguments);
if (!this.get("model.id")) return;
this.messageBus.unsubscribe("/staff/topic-assignment");
}
});
api.decorateWidget("post-contents:after-cooked", dec => {
if (dec.attrs.post_number === 1) {
const postModel = dec.getModel();
if (postModel) {
const assignedToUser = Ember.get(postModel, "topic.assigned_to_user");
if (assignedToUser) {
return dec.widget.attach("assigned-to", {
assignedToUser,
href: Ember.get(postModel, "topic.assignedToUserPath")
});
}
}
}
});
api.replaceIcon(
"notification.discourse_assign.assign_notification",
"user-plus"
);
api.modifyClass("controller:preferences/notifications", {
actions: {
save() {
this.saveAttrNames.push("custom_fields");
this._super(...arguments);
}
}
});
api.addKeyboardShortcut("g a", "", { path: "/my/activity/assigned" });
}
export default {
name: "extend-for-assign",
initialize(container) {
const siteSettings = container.lookup("site-settings:main");
if (!siteSettings.assign_enabled) {
return;
}
withPluginApi("0.8.11", api => initialize(api, container));
withPluginApi("0.8.28", api => registerTopicFooterButtons(api, container));
}
};