This repository has been archived on 2023-03-18. You can view files and clone it, but cannot push or open issues or pull requests.
osr-discourse-src/plugins/chat/assets/javascripts/discourse/controllers/create-channel.js
2023-02-24 12:47:42 +01:00

264 lines
6.9 KiB
JavaScript

import Modal from "discourse/controllers/modal";
import { escapeExpression } from "discourse/lib/utilities";
import { ajax } from "discourse/lib/ajax";
import { cancel } from "@ember/runloop";
import discourseDebounce from "discourse-common/lib/debounce";
import I18n from "I18n";
import { action, computed } from "@ember/object";
import { gt, notEmpty } from "@ember/object/computed";
import { inject as service } from "@ember/service";
import { isBlank, isPresent } from "@ember/utils";
import { htmlSafe } from "@ember/template";
const DEFAULT_HINT = htmlSafe(
I18n.t("chat.create_channel.choose_category.default_hint", {
link: "/categories",
category: "category",
})
);
export default class CreateChannelController extends Modal {
@service chat;
@service dialog;
@service chatChannelsManager;
@service chatApi;
@service router;
category = null;
categoryId = null;
name = "";
slug = "";
autoGeneratedSlug = "";
description = "";
categoryPermissionsHint = null;
autoJoinUsers = null;
autoJoinWarning = "";
@notEmpty("category") categorySelected;
@gt("siteSettings.max_chat_auto_joined_users", 0) autoJoinAvailable;
@computed("categorySelected", "name")
get createDisabled() {
return !this.categorySelected || isBlank(this.name);
}
@computed("categorySelected", "name")
get categoryName() {
return this.categorySelected && isPresent(this.name)
? escapeExpression(this.name)
: null;
}
onShow() {
this.set("categoryPermissionsHint", DEFAULT_HINT);
}
onClose() {
cancel(this.generateSlugHandler);
this.setProperties({
categoryId: null,
category: null,
name: "",
description: "",
slug: "",
autoGeneratedSlug: "",
categoryPermissionsHint: DEFAULT_HINT,
autoJoinWarning: "",
});
}
_createChannel() {
const data = {
chatable_id: this.categoryId,
name: this.name,
slug: this.slug || this.autoGeneratedSlug,
description: this.description,
auto_join_users: this.autoJoinUsers,
};
return this.chatApi
.createChannel(data)
.then((channel) => {
this.send("closeModal");
this.chatChannelsManager.follow(channel);
this.router.transitionTo("chat.channel", ...channel.routeModels);
})
.catch((e) => {
this.flash(e.jqXHR.responseJSON.errors[0], "error");
});
}
_buildCategorySlug(category) {
const parent = category.parentCategory;
if (parent) {
return `${this._buildCategorySlug(parent)}/${category.slug}`;
} else {
return category.slug;
}
}
_updateAutoJoinConfirmWarning(category, catPermissions) {
const allowedGroups = catPermissions.allowed_groups;
let warning;
if (catPermissions.private) {
switch (allowedGroups.length) {
case 1:
warning = I18n.t(
"chat.create_channel.auto_join_users.warning_1_group",
{
count: catPermissions.members_count,
group: escapeExpression(allowedGroups[0]),
}
);
break;
case 2:
warning = I18n.t(
"chat.create_channel.auto_join_users.warning_2_groups",
{
count: catPermissions.members_count,
group1: escapeExpression(allowedGroups[0]),
group2: escapeExpression(allowedGroups[1]),
}
);
break;
default:
warning = I18n.messageFormat(
"chat.create_channel.auto_join_users.warning_multiple_groups_MF",
{
groupCount: allowedGroups.length - 1,
userCount: catPermissions.members_count,
groupName: escapeExpression(allowedGroups[0]),
}
);
break;
}
} else {
warning = I18n.t(
"chat.create_channel.auto_join_users.public_category_warning",
{
category: escapeExpression(category.name),
}
);
}
this.set("autoJoinWarning", warning);
}
_updatePermissionsHint(category) {
if (category) {
const fullSlug = this._buildCategorySlug(category);
return this.chatApi
.categoryPermissions(category.id)
.then((catPermissions) => {
this._updateAutoJoinConfirmWarning(category, catPermissions);
const allowedGroups = catPermissions.allowed_groups;
const settingLink = `/c/${escapeExpression(fullSlug)}/edit/security`;
let hint;
switch (allowedGroups.length) {
case 1:
hint = I18n.t(
"chat.create_channel.choose_category.hint_1_group",
{
settingLink,
group: escapeExpression(allowedGroups[0]),
}
);
break;
case 2:
hint = I18n.t(
"chat.create_channel.choose_category.hint_2_groups",
{
settingLink,
group1: escapeExpression(allowedGroups[0]),
group2: escapeExpression(allowedGroups[1]),
}
);
break;
default:
hint = I18n.t(
"chat.create_channel.choose_category.hint_multiple_groups",
{
settingLink,
group: escapeExpression(allowedGroups[0]),
count: allowedGroups.length - 1,
}
);
break;
}
this.set("categoryPermissionsHint", htmlSafe(hint));
});
} else {
this.set("categoryPermissionsHint", DEFAULT_HINT);
this.set("autoJoinWarning", "");
}
}
// intentionally not showing AJAX error for this, we will autogenerate
// the slug server-side if they leave it blank
_generateSlug(name) {
ajax("/slugs.json", { type: "POST", data: { name } }).then((response) => {
this.set("autoGeneratedSlug", response.slug);
});
}
_debouncedGenerateSlug(name) {
cancel(this.generateSlugHandler);
this._clearAutoGeneratedSlug();
if (!name) {
return;
}
this.generateSlugHandler = discourseDebounce(
this,
this._generateSlug,
name,
300
);
}
_clearAutoGeneratedSlug() {
this.set("autoGeneratedSlug", "");
}
@action
onCategoryChange(categoryId) {
let category = categoryId
? this.site.categories.findBy("id", categoryId)
: null;
this._updatePermissionsHint(category);
const name = this.name || category?.name || "";
this.setProperties({
categoryId,
category,
name,
});
this._debouncedGenerateSlug(name);
}
@action
onNameChange(name) {
this._debouncedGenerateSlug(name);
}
@action
create() {
if (this.createDisabled) {
return;
}
if (this.autoJoinUsers) {
this.dialog.yesNoConfirm({
message: this.autoJoinWarning,
didConfirm: () => this._createChannel(),
});
} else {
this._createChannel();
}
}
}