discourse/app/assets/javascripts/select-kit/addon/components/user-chooser.js
David Taylor d1cc60c435
DEV: Convert select-kit components to native class syntax (#28489)
Changes made using the ember-native-class-codemod, plus some manual tweaks
2024-08-23 12:17:07 +01:00

113 lines
3.2 KiB
JavaScript

import { computed } from "@ember/object";
import { isPresent } from "@ember/utils";
import { classNames } from "@ember-decorators/component";
import userSearch, {
eagerCompleteSearch,
skipSearch,
} from "discourse/lib/user-search";
import { makeArray } from "discourse-common/lib/helpers";
import MultiSelectComponent from "select-kit/components/multi-select";
import {
pluginApiIdentifiers,
selectKitOptions,
} from "select-kit/components/select-kit";
export const CUSTOM_USER_SEARCH_OPTIONS = [];
@classNames("user-chooser")
@selectKitOptions({
topicId: undefined,
categoryId: undefined,
includeGroups: false,
allowedUsers: false,
includeMentionableGroups: false,
includeMessageableGroups: false,
allowEmails: false,
groupMembersOf: undefined,
excludeCurrentUser: false,
customSearchOptions: undefined,
excludedUsernames: undefined,
})
@pluginApiIdentifiers("user-chooser")
export default class UserChooser extends MultiSelectComponent {
valueProperty = "username";
modifyComponentForRow() {
return "user-chooser/user-row";
}
@computed("value.[]")
get content() {
return makeArray(this.value).map((x) => this.defaultItem(x, x));
}
@computed(
"value",
"currentUser",
"selectKit.options.{excludeCurrentUser,excludedUsernames}"
)
get excludedUsers() {
const options = this.selectKit.options;
let usernames = makeArray(this.value);
if (this.currentUser && options.excludeCurrentUser) {
usernames = usernames.concat([this.currentUser.username]);
}
return usernames.concat(options.excludedUsernames || []);
}
search(filter = "") {
filter = filter || "";
filter = filter.replace(/^@/, "");
const options = this.selectKit.options;
if (filter === "" && options?.customSearchOptions?.defaultSearchResults) {
return Promise.resolve(options.customSearchOptions.defaultSearchResults);
}
// prevents doing ajax request for nothing
const skippedSearch = skipSearch(filter, options.allowEmails);
const eagerComplete = eagerCompleteSearch(
filter,
options.topicId || options.categoryId
);
if (skippedSearch || (filter === "" && !eagerComplete)) {
return;
}
let customUserSearchOptions = {};
if (options.customSearchOptions && isPresent(CUSTOM_USER_SEARCH_OPTIONS)) {
customUserSearchOptions = CUSTOM_USER_SEARCH_OPTIONS.reduce(
(obj, option) => {
return {
...obj,
[option]: options.customSearchOptions[option],
};
},
{}
);
}
return userSearch({
term: filter,
topicId: options.topicId,
categoryId: options.categoryId,
exclude: this.excludedUsers,
includeGroups: options.includeGroups,
allowedUsers: options.allowedUsers,
includeMentionableGroups: options.includeMentionableGroups,
includeMessageableGroups: options.includeMessageableGroups,
groupMembersOf: options.groupMembersOf,
allowEmails: options.allowEmails,
includeStagedUsers: this.includeStagedUsers,
customUserSearchOptions,
}).then((result) => {
if (typeof result === "string") {
// do nothing promise probably got cancelled
} else {
return result;
}
});
}
}