continued

This commit is contained in:
Jarek Radosz 2023-06-20 19:32:18 +02:00
parent 86ecf26751
commit e0a2e14c11
No known key found for this signature in database
GPG Key ID: 62D0FBAE5BF9B953
47 changed files with 442 additions and 439 deletions

View File

@ -1,5 +1,6 @@
export default {
resource: "group",
map() {
this.route("assigned", function () {
this.route("show", { path: "/:filter" });

View File

@ -1,5 +1,6 @@
export default {
resource: "user.userPrivateMessages",
map() {
this.route("assigned", { path: "/assigned" }, function () {
this.route("index", { path: "/" });

View File

@ -1,5 +1,6 @@
export default {
resource: "user.userActivity",
map() {
this.route("assigned");
},

View File

@ -1,15 +1,15 @@
<div class="reviewable-filter discourse-assign-assign-to-filter">
<label class="filter-label">{{i18n "discourse_assign.assigned_to"}}</label>
<EmailGroupUserChooser
@value={{additionalFilters.assigned_to}}
@value={{this.additionalFilters.assigned_to}}
@onChange={{action "updateAssignedTo"}}
autocomplete="off"
@options={{hash
maximum=1
fullWidthWrap=true
filterPlaceholder=placeholderKey
filterPlaceholder=this.placeholderKey
includeGroups=false
groupMembersOf=allowedGroups
groupMembersOf=this.allowedGroups
}}
/>
</div>

View File

@ -4,7 +4,7 @@
}}</label>
<div class="controls">
<EmailGroupUserChooser
@value={{searchedTerms.assigned}}
@value={{this.searchedTerms.assigned}}
@onChange={{action "onChangeAssigned"}}
@options={{hash
maximum=1

View File

@ -4,7 +4,7 @@
<label class="checkbox-label">
<Input
@type="checkbox"
@checked={{readonly category.enable_unassigned_filter}}
@checked={{readonly this.category.enable_unassigned_filter}}
{{on "change" (action "onChangeSetting" value="target.checked")}}
/>
{{i18n "discourse_assign.add_unassigned_filter"}}

View File

@ -1 +1 @@
<GroupAssignedMenuItem @group={{group}} />
<GroupAssignedMenuItem @group={{this.group}} />

View File

@ -1,8 +1,7 @@
export default {
shouldRender(args, component) {
return (
component.currentUser &&
component.currentUser.can_assign &&
component.currentUser?.can_assign &&
args.group.can_show_assigned_tab &&
args.group.assignment_count > 0
);

View File

@ -9,9 +9,9 @@
<ComboBox
@name="alias"
@valueProperty="value"
@value={{assignableLevel}}
@content={{assignableLevelOptions}}
@value={{this.assignableLevel}}
@content={{this.assignableLevelOptions}}
@class="groups-form-assignable-level"
@onChange={{action (mut model.assignable_level)}}
@onChange={{action (mut this.model.assignable_level)}}
/>
</div>

View File

@ -15,6 +15,7 @@ export default {
{ name: I18n.t("groups.alias_levels.everyone"), value: 99 },
];
// TODO
defineProperty(
component,
"assignableLevel",

View File

@ -1,4 +1,4 @@
{{#if currentUser.can_assign}}
{{#if this.currentUser.can_assign}}
<LinkTo @route="userActivity.assigned">
{{d-icon "user-plus"}}
{{i18n "discourse_assign.assigned"}}

View File

@ -1,4 +1,4 @@
<LinkTo @route="userPrivateMessages.assigned" @model={{model}}>
<LinkTo @route="userPrivateMessages.assigned" @model={{this.model}}>
{{d-icon "user-plus" class="glyph"}}
{{i18n "discourse_assign.assigned"}}
</LinkTo>

View File

@ -1,9 +1,7 @@
export function shouldShowAssigned(args, component) {
const needsButton =
component.currentUser && component.currentUser.get("can_assign");
const needsButton = component.currentUser?.can_assign;
return (
needsButton &&
(!component.get("site.mobileView") || args.model.get("isPrivateMessage"))
needsButton && (!component.site.mobileView || args.model.isPrivateMessage)
);
}

View File

@ -1 +1 @@
<RemindAssignsFrequency @user={{model}} />
<RemindAssignsFrequency @user={{this.model}} />

View File

@ -1,5 +1,5 @@
export default {
shouldRender(args, component) {
return component.currentUser && component.currentUser.get("can_assign");
return component.currentUser?.can_assign;
},
};

View File

@ -8,17 +8,19 @@ import { isEmpty } from "@ember/utils";
import { ajax } from "discourse/lib/ajax";
import { popupAjaxError } from "discourse/lib/ajax-error";
export default Controller.extend(ModalFunctionality, {
topicBulkActions: controller(),
assignSuggestions: null,
allowedGroups: null,
taskActions: service(),
autofocus: not("capabilities.touch"),
assigneeName: or("model.username", "model.group_name"),
assigneeError: false,
export default class AssignUser extends Controller.extend(ModalFunctionality) {
@service taskActions;
@controller topicBulkActions;
init() {
this._super(...arguments);
assignSuggestions = null;
allowedGroups = null;
assigneeError = false;
@not("capabilities.touch") autofocus;
@or("model.username", "model.group_name") assigneeName;
constructor() {
super(...arguments);
this.set("allowedGroups", []);
this.set("assigneeError", false);
@ -31,17 +33,17 @@ export default Controller.extend(ModalFunctionality, {
this.set("allowedGroups", data.assign_allowed_on_groups);
this.set("allowedGroupsForAssignment", data.assign_allowed_for_groups);
});
},
}
onShow() {
this.set("assigneeError", false);
},
}
onClose() {
if (this.get("model.onClose") && this.get("model.username")) {
this.get("model.onClose")(this.get("model.username"));
if (this.model.onClose && this.model.username) {
this.model.onClose(this.model.username);
}
}
},
bulkAction(username, note) {
return this.topicBulkActions.performAndRefresh({
@ -49,19 +51,19 @@ export default Controller.extend(ModalFunctionality, {
username,
note,
});
},
}
@discourseComputed("siteSettings.enable_assign_status")
statusEnabled() {
return this.siteSettings.enable_assign_status;
},
}
@discourseComputed("siteSettings.assign_statuses")
availableStatuses() {
return this.siteSettings.assign_statuses.split("|").map((status) => {
return { id: status, name: status };
});
},
}
@discourseComputed("siteSettings.assign_statuses", "model.status")
status() {
@ -70,22 +72,19 @@ export default Controller.extend(ModalFunctionality, {
this.model.target.assignment_status ||
this.siteSettings.assign_statuses.split("|")[0]
);
},
}
@action
handleTextAreaKeydown(event) {
if ((event.ctrlKey || event.metaKey) && event.key === "Enter") {
this.assign();
}
},
}
@action
assign() {
if (this.isBulkAction) {
return this.bulkAction(
this.get("model.username"),
this.get("model.note")
);
return this.bulkAction(this.model.username, this.model.note);
}
if (!this.assigneeName) {
@ -95,18 +94,15 @@ export default Controller.extend(ModalFunctionality, {
let path = "/assign/assign";
if (isEmpty(this.get("model.username"))) {
if (isEmpty(this.model.username)) {
this.model.target.set("assigned_to_user", null);
}
if (isEmpty(this.get("model.group_name"))) {
if (isEmpty(this.model.group_name)) {
this.model.target.set("assigned_to_group", null);
}
if (
isEmpty(this.get("model.username")) &&
isEmpty(this.get("model.group_name"))
) {
if (isEmpty(this.model.username) && isEmpty(this.model.group_name)) {
path = "/assign/unassign";
}
@ -115,19 +111,19 @@ export default Controller.extend(ModalFunctionality, {
return ajax(path, {
type: "PUT",
data: {
username: this.get("model.username"),
group_name: this.get("model.group_name"),
target_id: this.get("model.target.id"),
target_type: this.get("model.targetType"),
note: this.get("model.note"),
status: this.get("model.status"),
username: this.model.username,
group_name: this.model.group_name,
target_id: this.model.target.id,
target_type: this.model.targetType,
note: this.model.note,
status: this.model.status,
},
})
.then(() => {
this.get("model.onSuccess")?.();
this.model.onSuccess?.();
})
.catch(popupAjaxError);
},
}
@action
assignUser(name) {
@ -136,27 +132,27 @@ export default Controller.extend(ModalFunctionality, {
if (name) {
return this.assign();
}
},
}
@action
assignUsername(selected) {
this.setGroupOrUser(selected.firstObject);
},
}
setGroupOrUser(name) {
this.set("assigneeError", false);
this.set("model.allowedGroups", this.taskActions.allowedGroups);
if (this.allowedGroupsForAssignment.includes(name)) {
this.setProperties({
"model.username": null,
"model.group_name": name,
"model.allowedGroups": this.taskActions.allowedGroups,
});
} else {
this.setProperties({
"model.username": name,
"model.group_name": null,
"model.allowedGroups": this.taskActions.allowedGroups,
});
}
},
});
}
}

View File

@ -6,22 +6,23 @@ import { inject as controller } from "@ember/controller";
import { inject as service } from "@ember/service";
import { action } from "@ember/object";
export default UserTopicsList.extend({
user: controller(),
taskActions: service(),
order: "",
ascending: false,
search: "",
bulkSelectEnabled: false,
selected: [],
canBulkSelect: alias("currentUser.staff"),
export default class GroupAssignedShow extends UserTopicsList {
@service taskActions;
@controller user;
queryParams: ["order", "ascending", "search"],
queryParams = ["order", "ascending", "search"];
order = "";
ascending = false;
search = "";
bulkSelectEnabled = false;
selected = [];
@alias("currentUser.staff") canBulkSelect;
_setSearchTerm(searchTerm) {
this.set("search", searchTerm);
this.refreshModel();
},
}
refreshModel() {
this.set("loading", true);
@ -39,21 +40,21 @@ export default UserTopicsList.extend({
.finally(() => {
this.set("loading", false);
});
},
}
@action
unassign(targetId, targetType = "Topic") {
this.taskActions
.unassign(targetId, targetType)
.then(() => this.send("changeAssigned"));
},
}
@action
reassign(topic) {
this.taskActions
.assign(topic)
.set("model.onSuccess", () => this.send("changeAssigned"));
},
}
@action
changeSort(sortBy) {
@ -64,20 +65,20 @@ export default UserTopicsList.extend({
this.setProperties({ order: sortBy, ascending: false });
this.refreshModel();
}
},
}
@action
onChangeFilter(value) {
discourseDebounce(this, this._setSearchTerm, value, INPUT_DELAY * 2);
},
}
@action
toggleBulkSelect() {
this.toggleProperty("bulkSelectEnabled");
},
}
@action
refresh() {
this.refreshModel();
},
});
}
}

View File

@ -6,33 +6,34 @@ import discourseComputed from "discourse-common/utils/decorators";
import discourseDebounce from "discourse-common/lib/debounce";
import { INPUT_DELAY } from "discourse-common/config/environment";
export default Controller.extend({
router: service(),
application: controller(),
loading: false,
offset: 0,
filterName: "",
filter: "",
export default class GroupAssigned extends Controller {
@service router;
@controller application;
loading = false;
offset = 0;
filterName = "";
filter = "";
@discourseComputed("router.currentRoute.queryParams.order")
order(order) {
return order || "";
},
}
@discourseComputed("router.currentRoute.queryParams.ascending")
ascending(ascending) {
return ascending || false;
},
}
@discourseComputed("router.currentRoute.queryParams.search")
search(search) {
return search || "";
},
}
@discourseComputed("site.mobileView")
isDesktop(mobileView) {
return !mobileView;
},
}
_setFilter(filter) {
this.set("loading", true);
@ -53,7 +54,7 @@ export default Controller.extend({
.finally(() => {
this.set("loading", false);
});
},
}
findMembers(refresh) {
if (refresh) {
@ -77,15 +78,15 @@ export default Controller.extend({
})
.finally(() => this.set("loading", false));
}
},
}
@action
loadMore() {
this.findMembers();
},
}
@action
onChangeFilterName(value) {
discourseDebounce(this, this._setFilter, value, INPUT_DELAY * 2);
},
});
}
}

View File

@ -12,7 +12,7 @@ import { htmlSafe } from "@ember/template";
export default class UserActivityAssigned extends UserTopicsList {
@service taskActions;
@controller user;
@controller user;
queryParams = ["order", "ascending", "search"];
order = "";

View File

@ -1,31 +1,24 @@
import DiscourseRoute from "discourse/routes/discourse";
import { findOrResetCachedTopicList } from "discourse/lib/cached-topic-list";
export default DiscourseRoute.extend({
export default class GroupAssignedShow extends DiscourseRoute {
beforeModel(transition) {
if (!(transition.hasOwnProperty("from") && transition.from)) {
return;
}
if (transition.from.localName === "show") {
if (transition.from?.localName === "show") {
this.session.set("topicListScrollPosition", 1);
}
},
}
model(params) {
let filter = null;
if (
["everyone", this.modelFor("group").get("name")].includes(params.filter)
) {
filter = `topics/group-topics-assigned/${this.modelFor("group").get(
"name"
)}`;
let filter;
if (["everyone", this.modelFor("group").name].includes(params.filter)) {
filter = `topics/group-topics-assigned/${this.modelFor("group").name}`;
} else {
filter = `topics/messages-assigned/${params.filter}`;
}
const lastTopicList = findOrResetCachedTopicList(this.session, filter);
return lastTopicList
? lastTopicList
: this.store.findFiltered("topicList", {
return (
findOrResetCachedTopicList(this.session, filter) ||
this.store.findFiltered("topicList", {
filter,
params: {
order: params.order,
@ -33,17 +26,18 @@ export default DiscourseRoute.extend({
search: params.search,
direct: params.filter !== "everyone",
},
});
},
})
);
}
setupController(controller, model) {
controller.setProperties({
model,
search: this.currentModel.params.search,
});
},
}
renderTemplate() {
this.render("group-topics-list");
},
});
}
}

View File

@ -2,10 +2,10 @@ import DiscourseRoute from "discourse/routes/discourse";
import { ajax } from "discourse/lib/ajax";
import { action } from "@ember/object";
export default DiscourseRoute.extend({
export default class GroupAssigned extends DiscourseRoute {
model() {
return ajax(`/assign/members/${this.modelFor("group").get("name")}`);
},
return ajax(`/assign/members/${this.modelFor("group").name}`);
}
setupController(controller, model) {
controller.setProperties({
@ -19,7 +19,7 @@ export default DiscourseRoute.extend({
});
controller.findMembers(true);
},
}
redirect(model, transition) {
if (transition.to.params.hasOwnProperty("filter")) {
@ -27,10 +27,10 @@ export default DiscourseRoute.extend({
} else {
this.transitionTo("group.assigned.show", "everyone");
}
},
}
@action
changeAssigned() {
this.refresh();
},
});
}
}

View File

@ -3,19 +3,19 @@ import UserTopicListRoute from "discourse/routes/user-topic-list";
import cookie from "discourse/lib/cookie";
import { action } from "@ember/object";
export default UserTopicListRoute.extend({
templateName: "user-activity-assigned",
controllerName: "user-activity-assigned",
export default class UserActivityAssigned extends UserTopicListRoute {
templateName = "user-activity-assigned";
controllerName = "user-activity-assigned";
userActionType: 16,
noContentHelpKey: "discourse_assigns.no_assigns",
userActionType = 16;
noContentHelpKey = "discourse_assigns.no_assigns";
beforeModel() {
if (!this.currentUser) {
cookie("destination_url", window.location.href);
this.transitionTo("login");
}
},
}
model(params) {
return this.store.findFiltered("topicList", {
@ -29,14 +29,14 @@ export default UserTopicListRoute.extend({
search: params.search,
},
});
},
}
titleToken() {
return I18n.t("discourse_assign.assigned");
},
}
@action
changeAssigned() {
this.refresh();
},
});
}
}

View File

@ -2,16 +2,16 @@ import I18n from "I18n";
import DropdownSelectBoxComponent from "select-kit/components/dropdown-select-box";
import { action } from "@ember/object";
export default DropdownSelectBoxComponent.extend({
classNames: ["assign-actions-dropdown"],
headerIcon: null,
allowInitialValueMutation: false,
showFullTitle: true,
selectKitOptions: {
export default class AssignActionsDropdown extends DropdownSelectBoxComponent {
classNames = ["assign-actions-dropdown"];
headerIcon = null;
allowInitialValueMutation = false;
showFullTitle = true;
selectKitOptions = {
icon: null,
translatedNone: "...",
showFullTitle: true,
},
};
computeContent() {
let options = [];
@ -49,7 +49,7 @@ export default DropdownSelectBoxComponent.extend({
});
}
return options;
},
}
@action
onSelect(id) {
@ -65,5 +65,5 @@ export default DropdownSelectBoxComponent.extend({
if (postId) {
this.unassign(postId, "Post");
}
},
});
}
}

View File

@ -1,5 +1,9 @@
{{avatar user imageSize="small"}}
<span class="assigned-username">
{{user.username}}
</span>
{{yield}}
<div class="assigned-to-user">
{{avatar @user imageSize="small"}}
<span class="assigned-username">
{{@user.username}}
</span>
{{yield}}
</div>

View File

@ -1,5 +0,0 @@
import Component from "@ember/component";
export default Component.extend({
classNames: ["assigned-to-user"],
});

View File

@ -5,84 +5,84 @@
This causes the topic-post-badge to be considered the same word as "text"
at the end of the link, preventing it from line wrapping onto its own line.
}}
{{#if bulkSelectEnabled}}
{{#if this.bulkSelectEnabled}}
<td class="bulk-select topic-list-data">
<input type="checkbox" class="bulk-select" />
</td>
{{/if}}
<td class="main-link clearfix topic-list-data" colspan="1">
<span class="link-top-line">
{{~raw "topic-status" topic=topic}}
{{~#if isPrivateMessage}}
{{~raw "topic-status" topic=this.topic}}
{{~#if this.isPrivateMessage}}
{{~d-icon "envelope" class="private-message-icon"}}
{{~/if}}
{{~topic-link topic class="raw-link raw-topic-link"}}
{{~#if topic.featured_link}}
{{~topic-featured-link topic}}
{{~topic-link this.topic class="raw-link raw-topic-link"}}
{{~#if this.topic.featured_link}}
{{~topic-featured-link this.topic}}
{{~/if}}
{{~#if showTopicPostBadges}}
{{~#if this.showTopicPostBadges}}
{{~raw
"topic-post-badges"
unread=topic.unread
unseen=topic.unseen
url=topic.lastUnreadUrl
newDotText=newDotText
unread=this.topic.unread
unseen=this.topic.unseen
url=this.topic.lastUnreadUrl
newDotText=this.newDotText
}}
{{~/if}}
</span>
<div class="link-bottom-line">
{{#unless hideCategory}}
{{#unless topic.isPinnedUncategorized}}
{{category-link topic.category}}
{{#unless this.hideCategory}}
{{#unless this.topic.isPinnedUncategorized}}
{{category-link this.topic.category}}
{{/unless}}
{{/unless}}
{{discourse-tags topic mode="list" tagsForUser=tagsForUser}}
{{discourse-tags this.topic mode="list" tagsForUser=this.tagsForUser}}
{{raw
"list/action-list"
topic=topic
postNumbers=topic.liked_post_numbers
topic=this.topic
postNumbers=this.topic.liked_post_numbers
className="likes"
icon="heart"
}}
</div>
{{#if expandPinned}}
{{raw "list/topic-excerpt" topic=topic}}
{{#if this.expandPinned}}
{{raw "list/topic-excerpt" topic=this.topic}}
{{/if}}
</td>
{{#if showPosters}}
{{raw "list/posters-column" posters=topic.featuredUsers}}
{{#if this.showPosters}}
{{raw "list/posters-column" posters=this.topic.featuredUsers}}
{{/if}}
{{raw "list/posts-count-column" topic=topic}}
{{raw "list/posts-count-column" topic=this.topic}}
<td class="num views {{topic.viewsHeat}} topic-list-data">{{number
topic.views
<td class="num views {{this.topic.viewsHeat}} topic-list-data">{{number
this.topic.views
numberKey="views_long"
}}</td>
{{raw
"list/activity-column"
topic=topic
topic=this.topic
class="num topic-list-data"
tagName="td"
}}
<td class="topic-list-data">
{{#if topic.assigned_to_user}}
{{#if this.topic.assigned_to_user}}
<AssignActionsDropdown
@topic={{topic}}
@assignee={{topic.assigned_to_user.username}}
@unassign={{unassign}}
@reassign={{reassign}}
@topic={{this.topic}}
@assignee={{this.topic.assigned_to_user.username}}
@unassign={{this.unassign}}
@reassign={{this.reassign}}
/>
{{else if topic.assigned_to_group}}
{{else if this.topic.assigned_to_group}}
<AssignActionsDropdown
@topic={{topic}}
@assignee={{topic.assigned_to_group.name}}
@topic={{this.topic}}
@assignee={{this.topic.assigned_to_group.name}}
@group={{true}}
@unassign={{unassign}}
@reassign={{reassign}}
@unassign={{this.unassign}}
@reassign={{this.reassign}}
/>
{{else}}
<AssignActionsDropdown @topic={{topic}} @unassign={{unassign}} />
<AssignActionsDropdown @topic={{this.topic}} @unassign={{this.unassign}} />
{{/if}}
</td>

View File

@ -1,7 +1,8 @@
import TopicListItem from "discourse/components/topic-list-item";
import { equal } from "@ember/object/computed";
export default TopicListItem.extend({
classNames: ["assigned-topic-list-item"],
isPrivateMessage: equal("topic.archetype", "private_message"),
});
export default class AssignedTopicListItem extends TopicListItem {
classNames = ["assigned-topic-list-item"];
@equal("topic.archetype", "private_message") isPrivateMessage;
}

View File

@ -1,42 +1,46 @@
{{#unless skipHeader}}
{{#unless this.skipHeader}}
<thead class="topic-list-header assigned-topic-list-header">
{{raw
"topic-list-header"
canBulkSelect=canBulkSelect
canDoBulkActions=canDoBulkActions
toggleInTitle=toggleInTitle
hideCategory=hideCategory
canBulkSelect=this.canBulkSelect
canDoBulkActions=this.canDoBulkActions
toggleInTitle=this.toggleInTitle
hideCategory=this.hideCategory
showPosters=true
showLikes=showLikes
showOpLikes=showOpLikes
order=order
ascending=ascending
sortable=sortable
listTitle=listTitle
bulkSelectEnabled=bulkSelectEnabled
showLikes=this.showLikes
showOpLikes=this.showOpLikes
order=this.order
ascending=this.ascending
sortable=this.sortable
listTitle=this.listTitle
bulkSelectEnabled=this.bulkSelectEnabled
}}
</thead>
{{/unless}}
<tbody class="topic-list-body assigned-topic-list-body">
{{#each filteredTopics as |topic|}}
{{#each this.filteredTopics as |topic|}}
<AssignedTopicListItem
@topic={{topic}}
@bulkSelectEnabled={{bulkSelectEnabled}}
@showTopicPostBadges={{showTopicPostBadges}}
@hideCategory={{hideCategory}}
@bulkSelectEnabled={{this.bulkSelectEnabled}}
@showTopicPostBadges={{this.showTopicPostBadges}}
@hideCategory={{this.hideCategory}}
@showPosters={{true}}
@showLikes={{showLikes}}
@showOpLikes={{showOpLikes}}
@expandGloballyPinned={{expandGloballyPinned}}
@expandAllPinned={{expandAllPinned}}
@lastVisitedTopic={{lastVisitedTopic}}
@selected={{selected}}
@tagsForUser={{tagsForUser}}
@unassign={{unassign}}
@reassign={{reassign}}
@showLikes={{this.showLikes}}
@showOpLikes={{this.showOpLikes}}
@expandGloballyPinned={{this.expandGloballyPinned}}
@expandAllPinned={{this.expandAllPinned}}
@lastVisitedTopic={{this.lastVisitedTopic}}
@selected={{this.selected}}
@tagsForUser={{this.tagsForUser}}
@unassign={{this.unassign}}
@reassign={{this.reassign}}
/>
{{raw "list/visited-line" lastVisitedTopic=lastVisitedTopic topic=topic}}
{{raw
"list/visited-line"
lastVisitedTopic=this.lastVisitedTopic
topic=topic
}}
{{/each}}
</tbody>

View File

@ -1,3 +1,3 @@
import EmailGroupUserChooserRow from "select-kit/components/email-group-user-chooser-row";
export default EmailGroupUserChooserRow.extend();
export default class AssigneeChooserRow extends EmailGroupUserChooserRow {}

View File

@ -1,7 +1,7 @@
import EmailGroupUserChooser from "select-kit/components/email-group-user-chooser";
export default EmailGroupUserChooser.extend({
export default class AssigneeChooser extends EmailGroupUserChooser {
modifyComponentForRow() {
return "assignee-chooser-row";
},
});
}
}

View File

@ -1,37 +1,37 @@
<ConditionalLoadingSpinner @condition={{loading}}>
{{#if hasIncoming}}
<ConditionalLoadingSpinner @condition={{this.loading}}>
{{#if this.hasIncoming}}
<div class="show-mores">
<a href class="alert alert-info clickable" {{action showInserted}}>
<a href class="alert alert-info clickable" {{action this.showInserted}}>
<CountI18n
@key="topic_count_"
@suffix="latest"
@count={{incomingCount}}
@count={{this.incomingCount}}
/>
</a>
</div>
{{/if}}
{{#if topics}}
{{#if this.topics}}
<AssignedTopicList
@showPosters={{showPosters}}
@hideCategory={{hideCategory}}
@topics={{topics}}
@expandExcerpts={{expandExcerpts}}
@bulkSelectEnabled={{bulkSelectEnabled}}
@canBulkSelect={{canBulkSelect}}
@bulkSelectAction={{bulkSelectAction}}
@selected={{selected}}
@skipHeader={{skipHeader}}
@tagsForUser={{tagsForUser}}
@changeSort={{changeSort}}
@toggleBulkSelect={{toggleBulkSelect}}
@unassign={{unassign}}
@reassign={{reassign}}
@onScroll={{onScroll}}
@scrollOnLoad={{scrollOnLoad}}
@showPosters={{this.showPosters}}
@hideCategory={{this.hideCategory}}
@topics={{this.topics}}
@expandExcerpts={{this.expandExcerpts}}
@bulkSelectEnabled={{this.bulkSelectEnabled}}
@canBulkSelect={{this.canBulkSelect}}
@bulkSelectAction={{this.bulkSelectAction}}
@selected={{this.selected}}
@skipHeader={{this.skipHeader}}
@tagsForUser={{this.tagsForUser}}
@changeSort={{this.changeSort}}
@toggleBulkSelect={{this.toggleBulkSelect}}
@unassign={{this.unassign}}
@reassign={{this.reassign}}
@onScroll={{this.onScroll}}
@scrollOnLoad={{this.scrollOnLoad}}
/>
{{else}}
{{#unless loadingMore}}
{{#unless this.loadingMore}}
<div class="alert alert-info">
{{i18n "choose_topic.none_found"}}
</div>

View File

@ -7,21 +7,21 @@ function assignIfEqual(topic, data) {
}
}
export default Component.extend({
export default class FlaggedTopicListener extends Component {
didInsertElement() {
this._super();
super.didInsertElement(...arguments);
this.messageBus.subscribe("/staff/topic-assignment", (data) => {
let flaggedTopics = this.flaggedTopics;
if (flaggedTopics) {
flaggedTopics.forEach((ft) => assignIfEqual(ft.topic, data));
if (this.flaggedTopics) {
this.flaggedTopics.forEach((ft) => assignIfEqual(ft.topic, data));
} else {
assignIfEqual(this.topic, data);
}
});
},
}
willDestroyElement() {
this._super();
super.willDestroyElement(...arguments);
this.messageBus.unsubscribe("/staff/topic-assignment");
},
});
}
}

View File

@ -1,53 +1,55 @@
{{#if showAvatar}}
<li>
{{#if @showAvatar}}
<LinkTo
@route="group.assigned.show"
@model={{filter.username_lower}}
@query={{hash order=order ascending=ascending search=search}}
@model={{@filter.username_lower}}
@query={{hash order=@order ascending=@ascending search=@search}}
>
<div class="assign-image">
<a href={{filter.userPath}} data-user-card={{filter.username}}>{{avatar
filter
imageSize="large"
}}</a>
<a
href={{@filter.userPath}}
data-user-card={{@filter.username}}
>{{avatar filter imageSize="large"}}</a>
</div>
<div class="assign-names">
<div class="assign-username">{{format-username filter.username}}</div>
<div class="assign-name">{{filter.name}}</div>
<div class="assign-username">{{format-username @filter.username}}</div>
<div class="assign-name">{{@filter.name}}</div>
</div>
<div class="assign-count">
{{filter.assignments_count}}
{{@filter.assignments_count}}
</div>
</LinkTo>
{{else if groupName}}
{{else if @groupName}}
<LinkTo
@route="group.assigned.show"
@model={{filter}}
@query={{hash order=order ascending=ascending search=search}}
@model={{@filter}}
@query={{hash order=@order ascending=@ascending search=@search}}
>
<div class="assign-image">
{{d-icon "group-plus"}}
</div>
<div class="assign-names">
<div class="assign-username">{{groupName}}</div>
<div class="assign-username">{{@groupName}}</div>
</div>
<div class="assign-count">
{{assignmentCount}}
{{@assignmentCount}}
</div>
</LinkTo>
{{else}}
{{else}}
<LinkTo
@route="group.assigned.show"
@model={{filter}}
@query={{hash order=order ascending=ascending search=search}}
@model={{@filter}}
@query={{hash order=@order ascending=@ascending search=@search}}
>
<div class="assign-everyone">
{{i18n "discourse_assign.group_everyone"}}
</div>
<div class="assign-count">
{{assignmentCount}}
{{@assignmentCount}}
</div>
</LinkTo>
{{/if}}
{{/if}}
</li>

View File

@ -1,5 +0,0 @@
import Component from "@ember/component";
export default Component.extend({
tagName: "li",
});

View File

@ -1,4 +1,4 @@
<LinkTo @route="group.assigned">
{{d-icon "group-plus" class="glyph"}}{{i18n "discourse_assign.assigned"}}
({{group.assignment_count}})
({{@group.assignment_count}})
</LinkTo>

View File

@ -1,5 +0,0 @@
import Component from "@ember/component";
export default Component.extend({
tagName: "",
});

View File

@ -1,12 +1,14 @@
{{#if siteSettings.assign_enabled}}
{{#if this.siteSettings.assign_enabled}}
<div class="controls controls-dropdown">
<label>{{i18n "discourse_assign.reminders_frequency.description"}}</label>
<ComboBox
@id="remind-assigns-frequency"
@valueProperty="value"
@content={{availableFrequencies}}
@value={{selectedFrequency}}
@onChange={{action (mut user.custom_fields.remind_assigns_frequency)}}
@content={{this.availableFrequencies}}
@value={{this.selectedFrequency}}
@onChange={{action
(mut this.user.custom_fields.remind_assigns_frequency)
}}
/>
</div>
{{/if}}

View File

@ -2,7 +2,7 @@ import Component from "@ember/component";
import I18n from "I18n";
import discourseComputed from "discourse-common/utils/decorators";
export default Component.extend({
export default class RemindAssignsFrequency extends Component {
@discourseComputed(
"user.custom_fields.remind_assigns_frequency",
"siteSettings.remind_assigns_frequency"
@ -17,16 +17,14 @@ export default Component.extend({
}
return siteDefaultAssignsFrequency;
},
}
@discourseComputed("user.reminders_frequency")
availableFrequencies(userRemindersFrequency) {
return userRemindersFrequency.map((freq) => {
return {
return userRemindersFrequency.map((freq) => ({
name: I18n.t(freq.name),
value: freq.value,
selected: false,
};
});
},
});
}));
}
}

View File

@ -2,7 +2,7 @@ import Service from "@ember/service";
import { ajax } from "discourse/lib/ajax";
import showModal from "discourse/lib/show-modal";
export default Service.extend({
export default class TaskActions extends Service {
i18nSuffix(targetType) {
switch (targetType) {
case "Post":
@ -10,7 +10,7 @@ export default Service.extend({
case "Topic":
return "_modal";
}
},
}
unassign(targetId, targetType = "Topic") {
return ajax("/assign/unassign", {
@ -20,7 +20,7 @@ export default Service.extend({
target_type: targetType,
},
});
},
}
assign(target, options = { isAssigned: false, targetType: "Topic" }) {
return showModal("assign-user", {
@ -37,7 +37,7 @@ export default Service.extend({
status: target.assignment_status,
},
});
},
}
reassignUserToTopic(user, target, targetType = "Topic") {
return ajax("/assign/assign", {
@ -49,5 +49,5 @@ export default Service.extend({
status: target.assignment_status,
},
});
},
});
}
}

View File

@ -2,7 +2,7 @@
<div class="inline-form full-width">
<Input
class="no-blur"
@value={{readonly search}}
@value={{readonly this.search}}
placeholder={{i18n "discourse_assign.topic_search_placeholder"}}
autocomplete="off"
@type="search"
@ -17,24 +17,24 @@
@action={{action "loadMore"}}
>
<BasicAssignedTopicList
@topicList={{model}}
@hideCategory={{hideCategory}}
@showPosters={{showPosters}}
@bulkSelectEnabled={{bulkSelectEnabled}}
@canBulkSelect={{canBulkSelect}}
@selected={{selected}}
@hasIncoming={{hasIncoming}}
@incomingCount={{incomingCount}}
@topicList={{this.model}}
@hideCategory={{this.hideCategory}}
@showPosters={{this.showPosters}}
@bulkSelectEnabled={{this.bulkSelectEnabled}}
@canBulkSelect={{this.canBulkSelect}}
@selected={{this.selected}}
@hasIncoming={{this.hasIncoming}}
@incomingCount={{this.incomingCount}}
@showInserted={{action "showInserted"}}
@tagsForUser={{tagsForUser}}
@tagsForUser={{this.tagsForUser}}
@changeSort={{action "changeSort"}}
@toggleBulkSelect={{action "toggleBulkSelect"}}
@bulkSelectAction={{action "refresh"}}
@unassign={{action "unassign"}}
@reassign={{action "reassign"}}
@onScroll={{saveScrollPosition}}
@onScroll={{this.saveScrollPosition}}
@scrollOnLoad={{true}}
/>
<ConditionalLoadingSpinner @condition={{model.loadingMore}} />
<ConditionalLoadingSpinner @condition={{this.model.loadingMore}} />
</LoadMore>

View File

@ -3,53 +3,58 @@
@class="activity-nav"
@desktopClass="action-list activity-list nav-stacked"
>
{{#if isDesktop}}
{{#if this.isDesktop}}
<div class="search-div">
<Input
@type="text"
placeholder={{i18n
"discourse_assign.sidebar_name_filter_placeholder"
}}
@value={{readonly filterName}}
@value={{readonly this.filterName}}
class="search"
{{on "input" (action "onChangeFilterName" value="target.value")}}
{{on "input" (action this.onChangeFilterName value="target.value")}}
/>
</div>
{{/if}}
<LoadMore @selector=".activity-nav li" @action={{action "loadMore"}}>
<GroupAssignedFilter
@showAvatar={{false}}
@filter="everyone"
@routeType={{route_type}}
@assignmentCount={{group.assignment_count}}
@search={{search}}
@ascending={{ascending}}
@order={{order}}
@routeType={{this.route_type}}
@assignmentCount={{this.group.assignment_count}}
@search={{this.search}}
@ascending={{this.ascending}}
@order={{this.order}}
/>
<GroupAssignedFilter
@showAvatar={{false}}
@groupName={{group.name}}
@filter={{group.name}}
@routeType={{route_type}}
@assignmentCount={{group.group_assignment_count}}
@search={{search}}
@ascending={{ascending}}
@order={{order}}
@groupName={{this.group.name}}
@filter={{this.group.name}}
@routeType={{this.route_type}}
@assignmentCount={{this.group.group_assignment_count}}
@search={{this.search}}
@ascending={{this.ascending}}
@order={{this.order}}
/>
{{#each members as |member|}}
{{#each this.members as |member|}}
<GroupAssignedFilter
@showAvatar={{true}}
@filter={{member}}
@routeType={{route_type}}
@search={{search}}
@ascending={{ascending}}
@order={{order}}
@routeType={{this.route_type}}
@search={{this.search}}
@ascending={{this.ascending}}
@order={{this.order}}
/>
{{/each}}
<ConditionalLoadingSpinner @condition={{loading}} />
<ConditionalLoadingSpinner @condition={{this.loading}} />
</LoadMore>
</MobileNav>
</section>
<section class="user-content">
{{outlet}}
</section>

View File

@ -1,25 +1,25 @@
<td class="topic-list-data">
<div class="main-link">
<TopicStatus @topic={{topic}} />
{{~#if isPrivateMessage}}
<TopicStatus @topic={{this.topic}} />
{{~#if this.isPrivateMessage}}
{{~d-icon "envelope" class="private-message-icon"}}
{{~/if}}
{{~topic-link topic}}
{{#if topic.unseen}}
{{~topic-link this.topic}}
{{#if this.topic.unseen}}
<span class="badge-notification new-topic"></span>
{{/if}}
{{#if topic.hasExcerpt}}
{{#if this.topic.hasExcerpt}}
<div class="topic-excerpt">
{{html-safe topic.excerpt}}
{{#if topic.excerptTruncated}}
{{#unless topic.canClearPin}}<a href={{topic.url}}>{{i18n
{{html-safe this.topic.excerpt}}
{{#if this.topic.excerptTruncated}}
{{#unless this.topic.canClearPin}}<a href={{this.topic.url}}>{{i18n
"read_more"
}}</a>{{/unless}}
{{/if}}
{{#if topic.canClearPin}}
{{#if this.topic.canClearPin}}
<a
href
{{action "clearPin" topic}}
{{action "clearPin" this.topic}}
title={{i18n "topic.clear_pin.help"}}
>{{i18n "topic.clear_pin.title"}}</a>
{{/if}}
@ -27,43 +27,49 @@
{{/if}}
</div>
<div class="pull-right topic-list-num">
{{#if topic.assigned_to_user}}
{{#if this.topic.assigned_to_user}}
<AssignActionsDropdown
@topic={{topic}}
@assignee={{topic.assigned_to_user.username}}
@unassign={{unassign}}
@reassign={{reassign}}
@topic={{this.topic}}
@assignee={{this.topic.assigned_to_user.username}}
@unassign={{this.unassign}}
@reassign={{this.reassign}}
/>
{{else if topic.assigned_to_group}}
{{else if this.topic.assigned_to_group}}
<AssignActionsDropdown
@topic={{topic}}
@assignee={{topic.assigned_to_group.name}}
@topic={{this.topic}}
@assignee={{this.topic.assigned_to_group.name}}
@group={{true}}
@unassign={{unassign}}
@reassign={{reassign}}
@unassign={{this.unassign}}
@reassign={{this.reassign}}
/>
{{else}}
<AssignActionsDropdown @topic={{topic}} @unassign={{unassign}} />
<AssignActionsDropdown
@topic={{this.topic}}
@unassign={{this.unassign}}
/>
{{/if}}
</div>
<div class="clearfix"></div>
<div class="topic-item-stats clearfix">
{{discourse-tags topic mode="list" tagsForUser=tagsForUser}}
{{discourse-tags this.topic mode="list" tagsForUser=this.tagsForUser}}
<div class="pull-right topic-list-num">
{{raw
"list/activity-column"
topic=topic
topic=this.topic
tagName="div"
class="num activity last"
}}
<a
href={{topic.lastPostUrl}}
title="{{i18n 'last_post'}}: {{html-safe raw-date topic.bumped_at}}"
>{{topic.last_poster_username}}</a>
href={{this.topic.lastPostUrl}}
title="{{i18n 'last_post'}}: {{html-safe
raw-date
this.topic.bumped_at
}}"
>{{this.topic.last_poster_username}}</a>
</div>
{{#unless hideCategory}}
{{#unless this.hideCategory}}
<div class="category">
{{category-link topic.category}}
{{category-link this.topic.category}}
</div>
{{/unless}}
<div class="clearfix"></div>

View File

@ -1,29 +1,33 @@
<ConditionalLoadingSpinner @condition={{loading}}>
{{#if hasIncoming}}
<ConditionalLoadingSpinner @condition={{this.loading}}>
{{#if this.hasIncoming}}
<div class="show-mores">
<a href class="alert alert-info clickable" {{action showInserted}}>
<a
href
class="alert alert-info clickable"
{{on "click" this.showInserted}}
>
<CountI18n
@key="topic_count_"
@suffix="latest"
@count={{incomingCount}}
@count={{this.incomingCount}}
/>
</a>
</div>
{{/if}}
{{#if topics}}
{{#if this.topics}}
<table class="topic-list assigned-topic-list">
<tbody class="topic-list-body assigned-topic-list-body">
{{#each topics as |t|}}
{{#each this.topics as |topic|}}
<AssignedTopicListItem
@topic={{t}}
@expandGloballyPinned={{expandGloballyPinned}}
@expandAllPinned={{expandAllPinned}}
@lastVisitedTopic={{lastVisitedTopic}}
@selected={{selected}}
@tagsForUser={{tagsForUser}}
@unassign={{unassign}}
@reassign={{reassign}}
@topic={{topic}}
@expandGloballyPinned={{this.expandGloballyPinned}}
@expandAllPinned={{this.expandAllPinned}}
@lastVisitedTopic={{this.lastVisitedTopic}}
@selected={{this.selected}}
@tagsForUser={{this.tagsForUser}}
@unassign={{this.unassign}}
@reassign={{this.reassign}}
/>
{{/each}}
</tbody>

View File

@ -4,22 +4,22 @@
<label>{{i18n "discourse_assign.assign_modal.assignee_label"}}</label>
<AssigneeChooser
autocomplete="off"
@value={{assigneeName}}
@value={{this.assigneeName}}
@onChange={{action "assignUsername"}}
autofocus="autofocus"
@showUserStatus={{true}}
@options={{hash
mobilePlacementStrategy="absolute"
filterPlaceholder=placeholderKey
filterPlaceholder=this.placeholderKey
includeGroups=true
customSearchOptions=(hash
assignableGroups=true defaultSearchResults=this.assignSuggestions
)
groupMembersOf=allowedGroups
groupMembersOf=this.allowedGroups
maximum=1
autofocus=autofocus
autofocus=this.autofocus
tabindex=1
expandedOnInsert=(not assigneeName)
expandedOnInsert=(not this.assigneeName)
caretUpIcon="search"
caretDownIcon="search"
}}
@ -37,9 +37,9 @@
<label>{{i18n "discourse_assign.assign_modal.status_label"}}</label>
<ComboBox
@id="assign-status"
@content={{availableStatuses}}
@value={{status}}
@onChange={{action (mut model.status)}}
@content={{this.availableStatuses}}
@value={{this.status}}
@onChange={{action (mut this.model.status)}}
/>
</div>
{{/if}}
@ -52,7 +52,7 @@
</label>
<Textarea
id={{"assign-modal-note"}}
@value={{model.note}}
@value={{this.model.note}}
{{! template-lint-disable no-down-event-binding }}
{{on "keydown" (action "handleTextAreaKeydown")}}
/>
@ -63,14 +63,14 @@
<div class="modal-footer">
<DButton
@label={{if
model.reassign
this.model.reassign
"discourse_assign.reassign.title"
"discourse_assign.assign_modal.assign"
}}
@icon={{inviteIcon}}
@icon={{this.inviteIcon}}
@action={{this.assign}}
class="btn-primary"
@disabled={{disabled}}
@disabled={{this.disabled}}
/>
<DModalCancel @close={{route-action "closeModal"}} />
</div>

View File

@ -1,7 +1,7 @@
{
"name": "discourse",
"version": "1.0.0",
"repository": "git@github.com:discourse/discourse-assign.git",
"version": "1.0.1",
"repository": "https://github.com/discourse/discourse-assign",
"author": "Discourse",
"license": "MIT",
"devDependencies": {

View File

@ -5,7 +5,6 @@
# version: 1.0.1
# authors: Sam Saffron
# url: https://github.com/discourse/discourse-assign
# transpile_js: true
enabled_site_setting :assign_enabled