mirror of
https://github.com/discourse/discourse.git
synced 2025-02-25 18:55:32 -06:00
FEATURE: allows to enable/disable threading in UI (#22307)
Enabling/Disabling threading has been possible through command line until now. This commit introduces two new UIs: - When creating a channel, it will be available once the category has been selected - On the settings page of a channel for admins
This commit is contained in:
parent
de2febcc0c
commit
ea0b8ca38c
@ -1,7 +1,7 @@
|
|||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
CHANNEL_EDITABLE_PARAMS = %i[name description slug]
|
CHANNEL_EDITABLE_PARAMS = %i[name description slug]
|
||||||
CATEGORY_CHANNEL_EDITABLE_PARAMS = %i[auto_join_users allow_channel_wide_mentions]
|
CATEGORY_CHANNEL_EDITABLE_PARAMS = %i[auto_join_users allow_channel_wide_mentions threading_enabled]
|
||||||
|
|
||||||
class Chat::Api::ChannelsController < Chat::ApiController
|
class Chat::Api::ChannelsController < Chat::ApiController
|
||||||
def index
|
def index
|
||||||
@ -36,7 +36,14 @@ class Chat::Api::ChannelsController < Chat::ApiController
|
|||||||
|
|
||||||
def create
|
def create
|
||||||
channel_params =
|
channel_params =
|
||||||
params.require(:channel).permit(:chatable_id, :name, :slug, :description, :auto_join_users)
|
params.require(:channel).permit(
|
||||||
|
:chatable_id,
|
||||||
|
:name,
|
||||||
|
:slug,
|
||||||
|
:description,
|
||||||
|
:auto_join_users,
|
||||||
|
:threading_enabled,
|
||||||
|
)
|
||||||
|
|
||||||
# NOTE: We don't allow creating channels for anything but category chatable types
|
# NOTE: We don't allow creating channels for anything but category chatable types
|
||||||
# at the moment. This may change in future, at which point we will need to pass in
|
# at the moment. This may change in future, at which point we will need to pass in
|
||||||
|
@ -10,6 +10,7 @@ module Chat
|
|||||||
# description: "This is the best channel",
|
# description: "This is the best channel",
|
||||||
# slug: "super-channel",
|
# slug: "super-channel",
|
||||||
# category_id: category.id,
|
# category_id: category.id,
|
||||||
|
# threading_enabled: true,
|
||||||
# )
|
# )
|
||||||
#
|
#
|
||||||
class CreateCategoryChannel
|
class CreateCategoryChannel
|
||||||
@ -23,6 +24,7 @@ module Chat
|
|||||||
# @option params_to_create [String] slug
|
# @option params_to_create [String] slug
|
||||||
# @option params_to_create [Boolean] auto_join_users
|
# @option params_to_create [Boolean] auto_join_users
|
||||||
# @option params_to_create [Integer] category_id
|
# @option params_to_create [Integer] category_id
|
||||||
|
# @option params_to_create [Boolean] threading_enabled
|
||||||
# @return [Service::Base::Context]
|
# @return [Service::Base::Context]
|
||||||
|
|
||||||
policy :can_create_channel
|
policy :can_create_channel
|
||||||
@ -42,8 +44,12 @@ module Chat
|
|||||||
attribute :slug, :string
|
attribute :slug, :string
|
||||||
attribute :category_id, :integer
|
attribute :category_id, :integer
|
||||||
attribute :auto_join_users, :boolean, default: false
|
attribute :auto_join_users, :boolean, default: false
|
||||||
|
attribute :threading_enabled, :boolean, default: false
|
||||||
|
|
||||||
before_validation { self.auto_join_users = auto_join_users.presence || false }
|
before_validation do
|
||||||
|
self.auto_join_users = auto_join_users.presence || false
|
||||||
|
self.threading_enabled = threading_enabled.presence || false
|
||||||
|
end
|
||||||
|
|
||||||
validates :category_id, presence: true
|
validates :category_id, presence: true
|
||||||
validates :name, length: { maximum: SiteSetting.max_topic_title_length }
|
validates :name, length: { maximum: SiteSetting.max_topic_title_length }
|
||||||
@ -70,6 +76,7 @@ module Chat
|
|||||||
description: contract.description,
|
description: contract.description,
|
||||||
user_count: 1,
|
user_count: 1,
|
||||||
auto_join_users: contract.auto_join_users,
|
auto_join_users: contract.auto_join_users,
|
||||||
|
threading_enabled: contract.threading_enabled,
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -3,8 +3,8 @@
|
|||||||
module Chat
|
module Chat
|
||||||
# Service responsible for updating a chat channel's name, slug, and description.
|
# Service responsible for updating a chat channel's name, slug, and description.
|
||||||
#
|
#
|
||||||
# For a CategoryChannel, the settings for auto_join_users and allow_channel_wide_mentions
|
# For a CategoryChannel, the settings for auto_join_users, allow_channel_wide_mentions
|
||||||
# are also editable.
|
# and threading_enabled are also editable.
|
||||||
#
|
#
|
||||||
# @example
|
# @example
|
||||||
# Service::Chat::UpdateChannel.call(
|
# Service::Chat::UpdateChannel.call(
|
||||||
@ -13,6 +13,7 @@ module Chat
|
|||||||
# name: "SuperChannel",
|
# name: "SuperChannel",
|
||||||
# description: "This is the best channel",
|
# description: "This is the best channel",
|
||||||
# slug: "super-channel",
|
# slug: "super-channel",
|
||||||
|
# threading_enaled: true,
|
||||||
# )
|
# )
|
||||||
#
|
#
|
||||||
class UpdateChannel
|
class UpdateChannel
|
||||||
@ -43,6 +44,7 @@ module Chat
|
|||||||
attribute :name, :string
|
attribute :name, :string
|
||||||
attribute :description, :string
|
attribute :description, :string
|
||||||
attribute :slug, :string
|
attribute :slug, :string
|
||||||
|
attribute :threading_enabled, :boolean, default: false
|
||||||
attribute :auto_join_users, :boolean, default: false
|
attribute :auto_join_users, :boolean, default: false
|
||||||
attribute :allow_channel_wide_mentions, :boolean, default: true
|
attribute :allow_channel_wide_mentions, :boolean, default: true
|
||||||
|
|
||||||
|
@ -1,36 +1,36 @@
|
|||||||
<div class="chat-form__section">
|
<div class="chat-form__section">
|
||||||
<div class="chat-form__field">
|
<div class="chat-form__field -mute">
|
||||||
<label class="chat-form__label">
|
<label class="chat-form__label">
|
||||||
<span>{{i18n "chat.settings.mute"}}</span>
|
<span>{{i18n "chat.settings.mute"}}</span>
|
||||||
<ChatChannelSettingsSavedIndicator
|
<ChatChannelSettingsSavedIndicator
|
||||||
@property={{this.channel.currentUserMembership.muted}}
|
@property={{@channel.currentUserMembership.muted}}
|
||||||
/>
|
/>
|
||||||
</label>
|
</label>
|
||||||
<div class="chat-form__control">
|
<div class="chat-form__control">
|
||||||
<ComboBox
|
<ComboBox
|
||||||
@content={{this.mutedOptions}}
|
@content={{this.mutedOptions}}
|
||||||
@value={{this.channel.currentUserMembership.muted}}
|
@value={{@channel.currentUserMembership.muted}}
|
||||||
@valueProperty="value"
|
@valueProperty="value"
|
||||||
@class="channel-settings-view__muted-selector"
|
@class="channel-settings-view__selector"
|
||||||
@onChange={{fn this.saveNotificationSettings "muted" "muted"}}
|
@onChange={{fn this.saveNotificationSettings "muted" "muted"}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{{#unless this.channel.currentUserMembership.muted}}
|
{{#unless @channel.currentUserMembership.muted}}
|
||||||
<div class="chat-form__field">
|
<div class="chat-form__field -desktop-notification-level">
|
||||||
<label class="chat-form__label">
|
<label class="chat-form__label">
|
||||||
<span>{{i18n "chat.settings.desktop_notification_level"}}</span>
|
<span>{{i18n "chat.settings.desktop_notification_level"}}</span>
|
||||||
<ChatChannelSettingsSavedIndicator
|
<ChatChannelSettingsSavedIndicator
|
||||||
@property={{this.channel.currentUserMembership.desktopNotificationLevel}}
|
@property={{@channel.currentUserMembership.desktopNotificationLevel}}
|
||||||
/>
|
/>
|
||||||
</label>
|
</label>
|
||||||
<div class="chat-form__control">
|
<div class="chat-form__control">
|
||||||
<ComboBox
|
<ComboBox
|
||||||
@content={{this.notificationLevels}}
|
@content={{this.notificationLevels}}
|
||||||
@value={{this.channel.currentUserMembership.desktopNotificationLevel}}
|
@value={{@channel.currentUserMembership.desktopNotificationLevel}}
|
||||||
@valueProperty="value"
|
@valueProperty="value"
|
||||||
@class="channel-settings-view__desktop-notification-level-selector"
|
@class="channel-settings-view__selector"
|
||||||
@onChange={{fn
|
@onChange={{fn
|
||||||
this.saveNotificationSettings
|
this.saveNotificationSettings
|
||||||
"desktopNotificationLevel"
|
"desktopNotificationLevel"
|
||||||
@ -40,19 +40,19 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="chat-form__field">
|
<div class="chat-form__field -mobile-notification-level">
|
||||||
<label class="chat-form__label">
|
<label class="chat-form__label">
|
||||||
<span>{{i18n "chat.settings.mobile_notification_level"}}</span>
|
<span>{{i18n "chat.settings.mobile_notification_level"}}</span>
|
||||||
<ChatChannelSettingsSavedIndicator
|
<ChatChannelSettingsSavedIndicator
|
||||||
@property={{this.channel.currentUserMembership.mobileNotificationLevel}}
|
@property={{@channel.currentUserMembership.mobileNotificationLevel}}
|
||||||
/>
|
/>
|
||||||
</label>
|
</label>
|
||||||
<div class="chat-form__control">
|
<div class="chat-form__control">
|
||||||
<ComboBox
|
<ComboBox
|
||||||
@content={{this.notificationLevels}}
|
@content={{this.notificationLevels}}
|
||||||
@value={{this.channel.currentUserMembership.mobileNotificationLevel}}
|
@value={{@channel.currentUserMembership.mobileNotificationLevel}}
|
||||||
@valueProperty="value"
|
@valueProperty="value"
|
||||||
@class="channel-settings-view__mobile-notification-level-selector"
|
@class="channel-settings-view__selector"
|
||||||
@onChange={{fn
|
@onChange={{fn
|
||||||
this.saveNotificationSettings
|
this.saveNotificationSettings
|
||||||
"mobileNotificationLevel"
|
"mobileNotificationLevel"
|
||||||
@ -64,7 +64,7 @@
|
|||||||
{{/unless}}
|
{{/unless}}
|
||||||
<div class="chat-retention-info">
|
<div class="chat-retention-info">
|
||||||
{{d-icon "info-circle"}}
|
{{d-icon "info-circle"}}
|
||||||
<ChatRetentionReminderText @channel={{this.channel}} />
|
<ChatRetentionReminderText @channel={{@channel}} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -72,28 +72,29 @@
|
|||||||
<h3 class="chat-form__section-admin-title">
|
<h3 class="chat-form__section-admin-title">
|
||||||
{{i18n "chat.settings.admin_title"}}
|
{{i18n "chat.settings.admin_title"}}
|
||||||
</h3>
|
</h3>
|
||||||
|
|
||||||
{{#if this.autoJoinAvailable}}
|
{{#if this.autoJoinAvailable}}
|
||||||
<div class="chat-form__section">
|
<div class="chat-form__section -autojoin">
|
||||||
<div class="chat-form__field">
|
<div class="chat-form__field">
|
||||||
<label class="chat-form__label">
|
<label class="chat-form__label">
|
||||||
<span>{{i18n "chat.settings.auto_join_users_label"}}</span>
|
<span>{{i18n "chat.settings.auto_join_users_label"}}</span>
|
||||||
<ChatChannelSettingsSavedIndicator
|
<ChatChannelSettingsSavedIndicator
|
||||||
@property={{this.channel.autoJoinUsers}}
|
@property={{@channel.autoJoinUsers}}
|
||||||
/>
|
/>
|
||||||
</label>
|
</label>
|
||||||
<ComboBox
|
<ComboBox
|
||||||
@content={{this.autoAddUsersOptions}}
|
@content={{this.autoAddUsersOptions}}
|
||||||
@value={{this.channel.autoJoinUsers}}
|
@value={{@channel.autoJoinUsers}}
|
||||||
@valueProperty="value"
|
@valueProperty="value"
|
||||||
@class="channel-settings-view__auto-join-selector"
|
@class="channel-settings-view__selector"
|
||||||
@onChange={{action
|
@onChange={{action
|
||||||
(fn this.onToggleAutoJoinUsers this.channel.autoJoinUsers)
|
(fn this.onToggleAutoJoinUsers @channel.autoJoinUsers)
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<p class="chat-form__description -autojoin">
|
<p class="chat-form__description">
|
||||||
{{i18n
|
{{i18n
|
||||||
"chat.settings.auto_join_users_info"
|
"chat.settings.auto_join_users_info"
|
||||||
category=this.channel.chatable.name
|
category=@channel.chatable.name
|
||||||
}}
|
}}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
@ -101,36 +102,62 @@
|
|||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
{{#if this.togglingChannelWideMentionsAvailable}}
|
{{#if this.togglingChannelWideMentionsAvailable}}
|
||||||
<div class="chat-form__section">
|
<div class="chat-form__section -channel-wide-mentions">
|
||||||
<div class="chat-form__field">
|
<div class="chat-form__field">
|
||||||
<label class="chat-form__label">
|
<label class="chat-form__label">
|
||||||
<span>{{i18n "chat.settings.channel_wide_mentions_label"}}</span>
|
<span>{{i18n "chat.settings.channel_wide_mentions_label"}}</span>
|
||||||
<ChatChannelSettingsSavedIndicator
|
<ChatChannelSettingsSavedIndicator
|
||||||
@property={{this.channel.allowChannelWideMentions}}
|
@property={{@channel.allowChannelWideMentions}}
|
||||||
/>
|
/>
|
||||||
</label>
|
</label>
|
||||||
<ComboBox
|
<ComboBox
|
||||||
@content={{this.channelWideMentionsOptions}}
|
@content={{this.channelWideMentionsOptions}}
|
||||||
@value={{this.channel.allowChannelWideMentions}}
|
@value={{@channel.allowChannelWideMentions}}
|
||||||
@valueProperty="value"
|
@valueProperty="value"
|
||||||
@class="channel-settings-view__channel-wide-mentions-selector"
|
@class="channel-settings-view__selector"
|
||||||
@onChange={{this.onToggleChannelWideMentions}}
|
@onChange={{this.onToggleChannelWideMentions}}
|
||||||
/>
|
/>
|
||||||
<p class="chat-form__description -channel-wide-mentions">
|
<p class="chat-form__description">
|
||||||
{{i18n
|
{{i18n
|
||||||
"chat.settings.channel_wide_mentions_description"
|
"chat.settings.channel_wide_mentions_description"
|
||||||
channel=this.channel.title
|
channel=@channel.title
|
||||||
}}
|
}}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
|
{{#if this.togglingThreadingAvailable}}
|
||||||
|
<div class="chat-form__section -threading">
|
||||||
|
<div class="chat-form__field">
|
||||||
|
<label class="chat-form__label">
|
||||||
|
<span>{{i18n "chat.settings.channel_threading_label"}}</span>
|
||||||
|
<span class="channel-settings-view__channel-threading-tooltip">
|
||||||
|
{{d-icon "info-circle"}}
|
||||||
|
<DTooltip>
|
||||||
|
{{i18n "chat.settings.channel_threading_description"}}
|
||||||
|
</DTooltip>
|
||||||
|
</span>
|
||||||
|
<ChatChannelSettingsSavedIndicator
|
||||||
|
@property={{@channel.threadingEnabled}}
|
||||||
|
/>
|
||||||
|
</label>
|
||||||
|
<ComboBox
|
||||||
|
@content={{this.threadingEnabledOptions}}
|
||||||
|
@value={{@channel.threadingEnabled}}
|
||||||
|
@valueProperty="value"
|
||||||
|
@class="channel-settings-view__selector"
|
||||||
|
@onChange={{this.onToggleThreadingEnabled}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
{{#unless this.channel.isDirectMessageChannel}}
|
{{#unless @channel.isDirectMessageChannel}}
|
||||||
<div class="chat-form__section">
|
<div class="chat-form__section">
|
||||||
{{#if (chat-guardian "can-edit-chat-channel")}}
|
{{#if (chat-guardian "can-edit-chat-channel")}}
|
||||||
{{#if (chat-guardian "can-archive-channel" this.channel)}}
|
{{#if (chat-guardian "can-archive-channel" @channel)}}
|
||||||
<div class="chat-form__field">
|
<div class="chat-form__field">
|
||||||
<DButton
|
<DButton
|
||||||
@action={{action "onArchiveChannel"}}
|
@action={{action "onArchiveChannel"}}
|
||||||
@ -141,7 +168,7 @@
|
|||||||
</div>
|
</div>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
{{#if this.channel.isClosed}}
|
{{#if @channel.isClosed}}
|
||||||
<div class="chat-form__field">
|
<div class="chat-form__field">
|
||||||
<DButton
|
<DButton
|
||||||
@action={{action "onToggleChannelState"}}
|
@action={{action "onToggleChannelState"}}
|
||||||
|
@ -1,9 +1,8 @@
|
|||||||
import Component from "@ember/component";
|
import Component from "@glimmer/component";
|
||||||
import { action, computed } from "@ember/object";
|
import { action } from "@ember/object";
|
||||||
import { inject as service } from "@ember/service";
|
import { inject as service } from "@ember/service";
|
||||||
import showModal from "discourse/lib/show-modal";
|
import showModal from "discourse/lib/show-modal";
|
||||||
import I18n from "I18n";
|
import I18n from "I18n";
|
||||||
import { reads } from "@ember/object/computed";
|
|
||||||
|
|
||||||
const NOTIFICATION_LEVELS = [
|
const NOTIFICATION_LEVELS = [
|
||||||
{ name: I18n.t("chat.notification_levels.never"), value: "never" },
|
{ name: I18n.t("chat.notification_levels.never"), value: "never" },
|
||||||
@ -21,6 +20,11 @@ const AUTO_ADD_USERS_OPTIONS = [
|
|||||||
{ name: I18n.t("no_value"), value: false },
|
{ name: I18n.t("no_value"), value: false },
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const THREADING_ENABLED_OPTIONS = [
|
||||||
|
{ name: I18n.t("chat.settings.threading_enabled"), value: true },
|
||||||
|
{ name: I18n.t("chat.settings.threading_disabled"), value: false },
|
||||||
|
];
|
||||||
|
|
||||||
const CHANNEL_WIDE_MENTIONS_OPTIONS = [
|
const CHANNEL_WIDE_MENTIONS_OPTIONS = [
|
||||||
{ name: I18n.t("yes_value"), value: true },
|
{ name: I18n.t("yes_value"), value: true },
|
||||||
{
|
{
|
||||||
@ -33,13 +37,14 @@ export default class ChatChannelSettingsView extends Component {
|
|||||||
@service chat;
|
@service chat;
|
||||||
@service chatApi;
|
@service chatApi;
|
||||||
@service chatGuardian;
|
@service chatGuardian;
|
||||||
|
@service currentUser;
|
||||||
|
@service siteSettings;
|
||||||
@service router;
|
@service router;
|
||||||
@service dialog;
|
@service dialog;
|
||||||
tagName = "";
|
|
||||||
channel = null;
|
|
||||||
|
|
||||||
notificationLevels = NOTIFICATION_LEVELS;
|
notificationLevels = NOTIFICATION_LEVELS;
|
||||||
mutedOptions = MUTED_OPTIONS;
|
mutedOptions = MUTED_OPTIONS;
|
||||||
|
threadingEnabledOptions = THREADING_ENABLED_OPTIONS;
|
||||||
autoAddUsersOptions = AUTO_ADD_USERS_OPTIONS;
|
autoAddUsersOptions = AUTO_ADD_USERS_OPTIONS;
|
||||||
channelWideMentionsOptions = CHANNEL_WIDE_MENTIONS_OPTIONS;
|
channelWideMentionsOptions = CHANNEL_WIDE_MENTIONS_OPTIONS;
|
||||||
isSavingNotificationSetting = false;
|
isSavingNotificationSetting = false;
|
||||||
@ -47,17 +52,25 @@ export default class ChatChannelSettingsView extends Component {
|
|||||||
savedMobileNotificationLevel = false;
|
savedMobileNotificationLevel = false;
|
||||||
savedMuted = false;
|
savedMuted = false;
|
||||||
|
|
||||||
@reads("channel.isCategoryChannel") togglingChannelWideMentionsAvailable;
|
get togglingChannelWideMentionsAvailable() {
|
||||||
|
return this.args.channel.isCategoryChannel;
|
||||||
|
}
|
||||||
|
|
||||||
@computed("channel.isCategoryChannel")
|
get togglingThreadingAvailable() {
|
||||||
get autoJoinAvailable() {
|
|
||||||
return (
|
return (
|
||||||
this.siteSettings.max_chat_auto_joined_users > 0 &&
|
this.siteSettings.enable_experimental_chat_threaded_discussions &&
|
||||||
this.channel.isCategoryChannel
|
this.args.channel.isCategoryChannel &&
|
||||||
|
this.currentUser?.admin
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
get autoJoinAvailable() {
|
||||||
|
return (
|
||||||
|
this.siteSettings.max_chat_auto_joined_users > 0 &&
|
||||||
|
this.args.channel.isCategoryChannel
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@computed("autoJoinAvailable", "togglingChannelWideMentionsAvailable")
|
|
||||||
get adminSectionAvailable() {
|
get adminSectionAvailable() {
|
||||||
return (
|
return (
|
||||||
this.chatGuardian.canEditChatChannel() &&
|
this.chatGuardian.canEditChatChannel() &&
|
||||||
@ -65,30 +78,29 @@ export default class ChatChannelSettingsView extends Component {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@computed(
|
|
||||||
"siteSettings.chat_allow_archiving_channels",
|
|
||||||
"channel.{isArchived,isReadOnly}"
|
|
||||||
)
|
|
||||||
get canArchiveChannel() {
|
get canArchiveChannel() {
|
||||||
return (
|
return (
|
||||||
this.siteSettings.chat_allow_archiving_channels &&
|
this.siteSettings.chat_allow_archiving_channels &&
|
||||||
!this.channel.isArchived &&
|
!this.args.channel.isArchived &&
|
||||||
!this.channel.isReadOnly
|
!this.args.channel.isReadOnly
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
saveNotificationSettings(frontendKey, backendKey, newValue) {
|
saveNotificationSettings(frontendKey, backendKey, newValue) {
|
||||||
if (this.channel.currentUserMembership[frontendKey] === newValue) {
|
if (this.args.channel.currentUserMembership[frontendKey] === newValue) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const settings = {};
|
const settings = {};
|
||||||
settings[backendKey] = newValue;
|
settings[backendKey] = newValue;
|
||||||
return this.chatApi
|
return this.chatApi
|
||||||
.updateCurrentUserChannelNotificationsSettings(this.channel.id, settings)
|
.updateCurrentUserChannelNotificationsSettings(
|
||||||
|
this.args.channel.id,
|
||||||
|
settings
|
||||||
|
)
|
||||||
.then((result) => {
|
.then((result) => {
|
||||||
this.channel.currentUserMembership[frontendKey] =
|
this.args.channel.currentUserMembership[frontendKey] =
|
||||||
result.membership[backendKey];
|
result.membership[backendKey];
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -96,76 +108,89 @@ export default class ChatChannelSettingsView extends Component {
|
|||||||
@action
|
@action
|
||||||
onArchiveChannel() {
|
onArchiveChannel() {
|
||||||
const controller = showModal("chat-channel-archive-modal");
|
const controller = showModal("chat-channel-archive-modal");
|
||||||
controller.set("chatChannel", this.channel);
|
controller.set("chatChannel", this.args.channel);
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
onDeleteChannel() {
|
onDeleteChannel() {
|
||||||
const controller = showModal("chat-channel-delete-modal");
|
const controller = showModal("chat-channel-delete-modal");
|
||||||
controller.set("chatChannel", this.channel);
|
controller.set("chatChannel", this.args.channel);
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
onToggleChannelState() {
|
onToggleChannelState() {
|
||||||
const controller = showModal("chat-channel-toggle");
|
const controller = showModal("chat-channel-toggle");
|
||||||
controller.set("chatChannel", this.channel);
|
controller.set("chatChannel", this.args.channel);
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
onToggleAutoJoinUsers() {
|
onToggleAutoJoinUsers() {
|
||||||
if (!this.channel.autoJoinUsers) {
|
if (!this.args.channel.autoJoinUsers) {
|
||||||
this.onEnableAutoJoinUsers();
|
this.onEnableAutoJoinUsers();
|
||||||
} else {
|
} else {
|
||||||
this.onDisableAutoJoinUsers();
|
this.onDisableAutoJoinUsers();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@action
|
||||||
|
onToggleThreadingEnabled(value) {
|
||||||
|
return this._updateChannelProperty(
|
||||||
|
this.args.channel,
|
||||||
|
"threading_enabled",
|
||||||
|
value
|
||||||
|
).then((result) => {
|
||||||
|
this.args.channel.threadingEnabled = result.channel.threading_enabled;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
onToggleChannelWideMentions() {
|
onToggleChannelWideMentions() {
|
||||||
const newValue = !this.channel.allowChannelWideMentions;
|
const newValue = !this.args.channel.allowChannelWideMentions;
|
||||||
if (this.channel.allowChannelWideMentions === newValue) {
|
if (this.args.channel.allowChannelWideMentions === newValue) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
return this._updateChannelProperty(
|
return this._updateChannelProperty(
|
||||||
this.channel,
|
this.args.channel,
|
||||||
"allow_channel_wide_mentions",
|
"allow_channel_wide_mentions",
|
||||||
newValue
|
newValue
|
||||||
).then((result) => {
|
).then((result) => {
|
||||||
this.channel.allowChannelWideMentions =
|
this.args.channel.allowChannelWideMentions =
|
||||||
result.channel.allow_channel_wide_mentions;
|
result.channel.allow_channel_wide_mentions;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
onDisableAutoJoinUsers() {
|
onDisableAutoJoinUsers() {
|
||||||
if (this.channel.autoJoinUsers === false) {
|
if (this.args.channel.autoJoinUsers === false) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
return this._updateChannelProperty(
|
return this._updateChannelProperty(
|
||||||
this.channel,
|
this.args.channel,
|
||||||
"auto_join_users",
|
"auto_join_users",
|
||||||
false
|
false
|
||||||
).then((result) => {
|
).then((result) => {
|
||||||
this.channel.autoJoinUsers = result.channel.auto_join_users;
|
this.args.channel.autoJoinUsers = result.channel.auto_join_users;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
onEnableAutoJoinUsers() {
|
onEnableAutoJoinUsers() {
|
||||||
if (this.channel.autoJoinUsers === true) {
|
if (this.args.channel.autoJoinUsers === true) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.dialog.confirm({
|
this.dialog.confirm({
|
||||||
message: I18n.t("chat.settings.auto_join_users_warning", {
|
message: I18n.t("chat.settings.auto_join_users_warning", {
|
||||||
category: this.channel.chatable.name,
|
category: this.args.channel.chatable.name,
|
||||||
}),
|
}),
|
||||||
didConfirm: () =>
|
didConfirm: () =>
|
||||||
this._updateChannelProperty(this.channel, "auto_join_users", true).then(
|
this._updateChannelProperty(
|
||||||
(result) => {
|
this.args.channel,
|
||||||
this.channel.autoJoinUsers = result.channel.auto_join_users;
|
"auto_join_users",
|
||||||
}
|
true
|
||||||
),
|
).then((result) => {
|
||||||
|
this.args.channel.autoJoinUsers = result.channel.auto_join_users;
|
||||||
|
}),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,6 +26,8 @@ export default class CreateChannelController extends Controller.extend(
|
|||||||
@service chatChannelsManager;
|
@service chatChannelsManager;
|
||||||
@service chatApi;
|
@service chatApi;
|
||||||
@service router;
|
@service router;
|
||||||
|
@service currentUser;
|
||||||
|
@service siteSettings;
|
||||||
|
|
||||||
category = null;
|
category = null;
|
||||||
categoryId = null;
|
categoryId = null;
|
||||||
@ -37,10 +39,18 @@ export default class CreateChannelController extends Controller.extend(
|
|||||||
autoJoinUsers = false;
|
autoJoinUsers = false;
|
||||||
autoJoinWarning = "";
|
autoJoinWarning = "";
|
||||||
loadingPermissionHint = false;
|
loadingPermissionHint = false;
|
||||||
|
threadingEnabled = false;
|
||||||
|
|
||||||
@notEmpty("category") categorySelected;
|
@notEmpty("category") categorySelected;
|
||||||
@gt("siteSettings.max_chat_auto_joined_users", 0) autoJoinAvailable;
|
@gt("siteSettings.max_chat_auto_joined_users", 0) autoJoinAvailable;
|
||||||
|
|
||||||
|
get threadingAvailable() {
|
||||||
|
return (
|
||||||
|
this.siteSettings.enable_experimental_chat_threaded_discussions &&
|
||||||
|
this.categorySelected
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
@computed("categorySelected", "name")
|
@computed("categorySelected", "name")
|
||||||
get createDisabled() {
|
get createDisabled() {
|
||||||
return !this.categorySelected || isBlank(this.name);
|
return !this.categorySelected || isBlank(this.name);
|
||||||
@ -78,6 +88,7 @@ export default class CreateChannelController extends Controller.extend(
|
|||||||
slug: this.slug || this.autoGeneratedSlug,
|
slug: this.slug || this.autoGeneratedSlug,
|
||||||
description: this.description,
|
description: this.description,
|
||||||
auto_join_users: this.autoJoinUsers,
|
auto_join_users: this.autoJoinUsers,
|
||||||
|
threading_enabled: this.threadingEnabled,
|
||||||
};
|
};
|
||||||
|
|
||||||
return this.chatApi
|
return this.chatApi
|
||||||
|
@ -1,50 +1,50 @@
|
|||||||
<DModalBody @title="chat.create_channel.title">
|
<DModalBody @title="chat.create_channel.title">
|
||||||
<div class="create-channel-control">
|
<div class="create-channel__control -name">
|
||||||
<label for="channel-name" class="create-channel-label">
|
<label for="channel-name" class="create-channel__label">
|
||||||
{{i18n "chat.create_channel.name"}}
|
{{i18n "chat.create_channel.name"}}
|
||||||
</label>
|
</label>
|
||||||
<Input
|
<Input
|
||||||
name="channel-name"
|
name="channel-name"
|
||||||
class="create-channel-name-input"
|
class="create-channel__input"
|
||||||
@type="text"
|
@type="text"
|
||||||
@value={{this.name}}
|
@value={{this.name}}
|
||||||
{{on "input" (action "onNameChange" value="target.value")}}
|
{{on "input" (action "onNameChange" value="target.value")}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="create-channel-control">
|
<div class="create-channel__control -slug">
|
||||||
<label for="channel-slug" class="create-channel-label">
|
<label for="channel-slug" class="create-channel__label">
|
||||||
{{i18n "chat.create_channel.slug"}}
|
{{i18n "chat.create_channel.slug"}}
|
||||||
<span>
|
<span>
|
||||||
{{d-icon "info-circle"}}
|
{{d-icon "info-circle"}}
|
||||||
<DTooltip>{{i18n
|
<DTooltip>
|
||||||
"chat.channel_edit_name_slug_modal.slug_description"
|
{{i18n "chat.channel_edit_name_slug_modal.slug_description"}}
|
||||||
}}</DTooltip>
|
</DTooltip>
|
||||||
</span>
|
</span>
|
||||||
</label>
|
</label>
|
||||||
<Input
|
<Input
|
||||||
name="channel-slug"
|
name="channel-slug"
|
||||||
class="create-channel-slug-input"
|
class="create-channel__input"
|
||||||
@type="text"
|
@type="text"
|
||||||
@value={{this.slug}}
|
@value={{this.slug}}
|
||||||
placeholder={{this.autoGeneratedSlug}}
|
placeholder={{this.autoGeneratedSlug}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="create-channel-control">
|
<div class="create-channel__control -description">
|
||||||
<label for="channel-description" class="create-channel-label">
|
<label for="channel-description" class="create-channel__label">
|
||||||
{{i18n "chat.create_channel.description"}}
|
{{i18n "chat.create_channel.description"}}
|
||||||
</label>
|
</label>
|
||||||
<Input
|
<Input
|
||||||
name="channel-description"
|
name="channel-description"
|
||||||
class="create-channel-description-input"
|
class="create-channel__input"
|
||||||
@type="textarea"
|
@type="textarea"
|
||||||
@value={{this.description}}
|
@value={{this.description}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="create-channel-control">
|
<div class="create-channel__control">
|
||||||
<label class="create-channel-label">
|
<label class="create-channel__label">
|
||||||
{{i18n "chat.create_channel.choose_category.label"}}
|
{{i18n "chat.create_channel.choose_category.label"}}
|
||||||
</label>
|
</label>
|
||||||
<CategoryChooser
|
<CategoryChooser
|
||||||
@ -56,7 +56,7 @@
|
|||||||
{{#if this.categoryPermissionsHint}}
|
{{#if this.categoryPermissionsHint}}
|
||||||
<div
|
<div
|
||||||
class={{concat-class
|
class={{concat-class
|
||||||
"create-channel-hint"
|
"create-channel__hint"
|
||||||
(if this.loadingPermissionHint "loading-permissions")
|
(if this.loadingPermissionHint "loading-permissions")
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
@ -66,14 +66,14 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{{#if this.autoJoinAvailable}}
|
{{#if this.autoJoinAvailable}}
|
||||||
<div class="create-channel-control">
|
<div class="create-channel__control -auto-join">
|
||||||
<label class="create-channel-label">
|
<label class="create-channel__label">
|
||||||
<Input @type="checkbox" @checked={{this.autoJoinUsers}} />
|
<Input @type="checkbox" @checked={{this.autoJoinUsers}} />
|
||||||
<div class="auto-join-channel">
|
<div class="auto-join-channel">
|
||||||
<span class="auto-join-channel__label">
|
<span class="create-channel__label-title">
|
||||||
{{i18n "chat.settings.auto_join_users_label"}}
|
{{i18n "chat.settings.auto_join_users_label"}}
|
||||||
</span>
|
</span>
|
||||||
<p class="auto-join-channel__description">
|
<p class="create-channel__label-description">
|
||||||
{{#if this.categoryName}}
|
{{#if this.categoryName}}
|
||||||
{{i18n
|
{{i18n
|
||||||
"chat.settings.auto_join_users_info"
|
"chat.settings.auto_join_users_info"
|
||||||
@ -87,6 +87,22 @@
|
|||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
|
{{#if this.threadingAvailable}}
|
||||||
|
<div class="create-channel__control -threading-toggle">
|
||||||
|
<label class="create-channel__label">
|
||||||
|
<Input @type="checkbox" @checked={{this.threadingEnabled}} />
|
||||||
|
<div class="threading-channel">
|
||||||
|
<span class="create-channel__label-title">
|
||||||
|
{{i18n "chat.create_channel.threading.label"}}
|
||||||
|
</span>
|
||||||
|
<p class="create-channel__label-description">
|
||||||
|
{{i18n "chat.settings.channel_threading_description"}}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
</DModalBody>
|
</DModalBody>
|
||||||
|
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
|
@ -37,14 +37,17 @@
|
|||||||
font-size: var(--font-down-2);
|
font-size: var(--font-down-2);
|
||||||
}
|
}
|
||||||
|
|
||||||
.channel-settings-view__desktop-notification-level-selector,
|
.channel-settings-view__selector {
|
||||||
.channel-settings-view__mobile-notification-level-selector,
|
|
||||||
.channel-settings-view__muted-selector,
|
|
||||||
.channel-settings-view__auto-join-selector,
|
|
||||||
.channel-settings-view__channel-wide-mentions-selector {
|
|
||||||
width: 220px;
|
width: 220px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.channel-settings-view__channel-threading-tooltip {
|
||||||
|
padding-left: 0.25rem;
|
||||||
|
color: var(--tertiary);
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.channel-settings-view__muted-selector,
|
||||||
.chat-form__btn.delete-btn {
|
.chat-form__btn.delete-btn {
|
||||||
.d-icon {
|
.d-icon {
|
||||||
color: var(--danger);
|
color: var(--danger);
|
||||||
|
@ -9,9 +9,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.select-kit.combo-box,
|
.select-kit.combo-box,
|
||||||
.create-channel-name-input,
|
.create-channel__input,
|
||||||
.create-channel-slug-input,
|
|
||||||
.create-channel-description-input,
|
|
||||||
#choose-topic-title {
|
#choose-topic-title {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
@ -24,23 +22,21 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.create-channel-hint {
|
.create-channel__hint {
|
||||||
font-size: var(--font-down-1);
|
font-size: var(--font-down-1);
|
||||||
padding-top: 0.25rem;
|
padding-top: 0.25rem;
|
||||||
color: var(--secondary-low);
|
color: var(--secondary-low);
|
||||||
}
|
}
|
||||||
|
|
||||||
.create-channel-control,
|
.create-channel__control,
|
||||||
.edit-channel-control {
|
.edit-channel-control {
|
||||||
margin-bottom: 1rem;
|
margin-bottom: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.auto-join-channel {
|
.create-channel__label-description {
|
||||||
&__description {
|
margin: 0;
|
||||||
margin: 0;
|
padding-top: 0.25rem;
|
||||||
padding-top: 0.25rem;
|
color: var(--secondary-low);
|
||||||
color: var(--secondary-low);
|
font-size: var(--font-down-1) !important;
|
||||||
font-size: var(--font-down-1) !important;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -354,6 +354,8 @@ en:
|
|||||||
other: "%{count} members"
|
other: "%{count} members"
|
||||||
|
|
||||||
create_channel:
|
create_channel:
|
||||||
|
threading:
|
||||||
|
label: "Enable threading"
|
||||||
auto_join_users:
|
auto_join_users:
|
||||||
public_category_warning: "%{category} is a public category. Automatically add all recently active users to this channel?"
|
public_category_warning: "%{category} is a public category. Automatically add all recently active users to this channel?"
|
||||||
warning_1_group:
|
warning_1_group:
|
||||||
@ -431,6 +433,8 @@ en:
|
|||||||
settings:
|
settings:
|
||||||
channel_wide_mentions_label: "Allow @all and @here mentions"
|
channel_wide_mentions_label: "Allow @all and @here mentions"
|
||||||
channel_wide_mentions_description: "Allow users to notify all members of #%{channel} with @all or only those who are active in the moment with @here"
|
channel_wide_mentions_description: "Allow users to notify all members of #%{channel} with @all or only those who are active in the moment with @here"
|
||||||
|
channel_threading_label: "Threading"
|
||||||
|
channel_threading_description: "When threading is enabled, replies to a chat message will create a separate conversation, which will exist alongside the main channel."
|
||||||
auto_join_users_label: "Automatically add users"
|
auto_join_users_label: "Automatically add users"
|
||||||
auto_join_users_info: "Check hourly which users have been active in the last 3 months. Add them to this channel if they have access to the %{category} category."
|
auto_join_users_info: "Check hourly which users have been active in the last 3 months. Add them to this channel if they have access to the %{category} category."
|
||||||
auto_join_users_info_no_category: "Check hourly which users have been active in the last 3 months. Add them to this channel if they have access to the selected category."
|
auto_join_users_info_no_category: "Check hourly which users have been active in the last 3 months. Add them to this channel if they have access to the selected category."
|
||||||
@ -440,6 +444,8 @@ en:
|
|||||||
followed: "Joined"
|
followed: "Joined"
|
||||||
mobile_notification_level: "Mobile push notifications"
|
mobile_notification_level: "Mobile push notifications"
|
||||||
mute: "Mute channel"
|
mute: "Mute channel"
|
||||||
|
threading_enabled: "Enabled"
|
||||||
|
threading_disabled: "Disabled"
|
||||||
muted_on: "On"
|
muted_on: "On"
|
||||||
muted_off: "Off"
|
muted_off: "Off"
|
||||||
notifications: "Notifications"
|
notifications: "Notifications"
|
||||||
|
@ -629,6 +629,7 @@ RSpec.describe Chat::Api::ChannelsController do
|
|||||||
chatable_id: category.id,
|
chatable_id: category.id,
|
||||||
name: "channel name",
|
name: "channel name",
|
||||||
description: "My new channel",
|
description: "My new channel",
|
||||||
|
threading_enabled: false,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
@ -691,6 +692,25 @@ RSpec.describe Chat::Api::ChannelsController do
|
|||||||
expect(new_channel.auto_join_users).to eq(true)
|
expect(new_channel.auto_join_users).to eq(true)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "creates a channel sets threading_enabled to false by default" do
|
||||||
|
post "/chat/api/channels", params: params
|
||||||
|
expect(response.status).to eq(200)
|
||||||
|
|
||||||
|
new_channel = Chat::Channel.find(response.parsed_body.dig("channel", "id"))
|
||||||
|
|
||||||
|
expect(new_channel.threading_enabled).to eq(false)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "creates a channel with threading_enabled set to true" do
|
||||||
|
params[:channel][:threading_enabled] = true
|
||||||
|
post "/chat/api/channels", params: params
|
||||||
|
expect(response.status).to eq(200)
|
||||||
|
|
||||||
|
new_channel = Chat::Channel.find(response.parsed_body.dig("channel", "id"))
|
||||||
|
|
||||||
|
expect(new_channel.threading_enabled).to eq(true)
|
||||||
|
end
|
||||||
|
|
||||||
describe "triggers the auto-join process" do
|
describe "triggers the auto-join process" do
|
||||||
fab!(:chatters_group) { Fabricate(:group) }
|
fab!(:chatters_group) { Fabricate(:group) }
|
||||||
fab!(:user) { Fabricate(:user, last_seen_at: 15.minute.ago) }
|
fab!(:user) { Fabricate(:user, last_seen_at: 15.minute.ago) }
|
||||||
@ -884,6 +904,18 @@ RSpec.describe Chat::Api::ChannelsController do
|
|||||||
expect(response.parsed_body["channel"]).to match_response_schema("category_chat_channel")
|
expect(response.parsed_body["channel"]).to match_response_schema("category_chat_channel")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe "when updating threading_enabled" do
|
||||||
|
before { SiteSetting.enable_experimental_chat_threaded_discussions = true }
|
||||||
|
|
||||||
|
it "sets the new value" do
|
||||||
|
expect {
|
||||||
|
put "/chat/api/channels/#{channel.id}", params: { channel: { threading_enabled: true } }
|
||||||
|
}.to change { channel.reload.threading_enabled }.from(false).to(true)
|
||||||
|
|
||||||
|
expect(response.parsed_body["channel"]["threading_enabled"]).to eq(true)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
describe "when updating allow_channel_wide_mentions" do
|
describe "when updating allow_channel_wide_mentions" do
|
||||||
it "sets the new value" do
|
it "sets the new value" do
|
||||||
put "/chat/api/channels/#{channel.id}",
|
put "/chat/api/channels/#{channel.id}",
|
||||||
|
@ -93,6 +93,29 @@ RSpec.describe Chat::CreateCategoryChannel do
|
|||||||
result
|
result
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe "threading_enabled" do
|
||||||
|
context "when true" do
|
||||||
|
it "sets threading_enabled to true" do
|
||||||
|
params[:threading_enabled] = true
|
||||||
|
expect(result.channel.threading_enabled).to eq(true)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "when blank" do
|
||||||
|
it "sets threading_enabled to false" do
|
||||||
|
params[:threading_enabled] = nil
|
||||||
|
expect(result.channel.threading_enabled).to eq(false)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "when false" do
|
||||||
|
it "sets threading_enabled to false" do
|
||||||
|
params[:threading_enabled] = false
|
||||||
|
expect(result.channel.threading_enabled).to eq(false)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -63,45 +63,73 @@ RSpec.describe Chat::UpdateChannel do
|
|||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
context "when the name is blank" do
|
describe "name" do
|
||||||
before { params[:name] = "" }
|
context "when blank" do
|
||||||
|
before { params[:name] = "" }
|
||||||
|
|
||||||
it "nils out the name" do
|
it "nils out the name" do
|
||||||
result
|
result
|
||||||
expect(channel.reload.name).to be_nil
|
expect(channel.reload.name).to be_nil
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context "when the description is blank" do
|
describe "description" do
|
||||||
before do
|
context "when blank" do
|
||||||
channel.update!(description: "something")
|
before do
|
||||||
params[:description] = ""
|
channel.update!(description: "something")
|
||||||
end
|
params[:description] = ""
|
||||||
|
end
|
||||||
|
|
||||||
it "nils out the description" do
|
it "nils out the description" do
|
||||||
result
|
result
|
||||||
expect(channel.reload.description).to be_nil
|
expect(channel.reload.description).to be_nil
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context "when auto_join_users is set to 'true'" do
|
describe "#auto_join_users" do
|
||||||
before do
|
context "when set to 'true'" do
|
||||||
channel.update!(auto_join_users: false)
|
before do
|
||||||
params[:auto_join_users] = true
|
channel.update!(auto_join_users: false)
|
||||||
|
params[:auto_join_users] = true
|
||||||
|
end
|
||||||
|
|
||||||
|
it "updates the model accordingly" do
|
||||||
|
result
|
||||||
|
expect(channel.reload).to have_attributes(auto_join_users: true)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "auto joins users" do
|
||||||
|
expect_enqueued_with(
|
||||||
|
job: Jobs::Chat::AutoJoinChannelMemberships,
|
||||||
|
args: {
|
||||||
|
chat_channel_id: channel.id,
|
||||||
|
},
|
||||||
|
) { result }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "threading_enabled" do
|
||||||
|
context "when true" do
|
||||||
|
it "changes the value to true" do
|
||||||
|
expect {
|
||||||
|
params[:threading_enabled] = true
|
||||||
|
result
|
||||||
|
}.to change { channel.reload.threading_enabled }.from(false).to(true)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
it "updates the model accordingly" do
|
context "when false" do
|
||||||
result
|
it "changes the value to true" do
|
||||||
expect(channel.reload).to have_attributes(auto_join_users: true)
|
channel.update!(threading_enabled: true)
|
||||||
end
|
|
||||||
|
|
||||||
it "auto joins users" do
|
expect {
|
||||||
expect_enqueued_with(
|
params[:threading_enabled] = false
|
||||||
job: Jobs::Chat::AutoJoinChannelMemberships,
|
result
|
||||||
args: {
|
}.to change { channel.reload.threading_enabled }.from(true).to(false)
|
||||||
chat_channel_id: channel.id,
|
end
|
||||||
},
|
|
||||||
) { result }
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -56,7 +56,7 @@ RSpec.describe "Channel - Info - Settings page", type: :system do
|
|||||||
context "as a member" do
|
context "as a member" do
|
||||||
before { channel_1.add(current_user) }
|
before { channel_1.add(current_user) }
|
||||||
|
|
||||||
context "when visitng the settings of a recently joined channel" do
|
context "when visiting the settings of a recently joined channel" do
|
||||||
fab!(:channel_2) { Fabricate(:category_channel) }
|
fab!(:channel_2) { Fabricate(:category_channel) }
|
||||||
|
|
||||||
it "is correctly populated" do
|
it "is correctly populated" do
|
||||||
@ -82,8 +82,11 @@ RSpec.describe "Channel - Info - Settings page", type: :system do
|
|||||||
membership = channel_1.membership_for(current_user)
|
membership = channel_1.membership_for(current_user)
|
||||||
|
|
||||||
expect {
|
expect {
|
||||||
find(".channel-settings-view__muted-selector").click
|
select_kit =
|
||||||
find(".channel-settings-view__muted-selector [data-name='On']").click
|
PageObjects::Components::SelectKit.new(".-mute .channel-settings-view__selector")
|
||||||
|
select_kit.expand
|
||||||
|
select_kit.select_row_by_name("On")
|
||||||
|
|
||||||
expect(page).to have_content(I18n.t("js.chat.settings.saved"))
|
expect(page).to have_content(I18n.t("js.chat.settings.saved"))
|
||||||
}.to change { membership.reload.muted }.from(false).to(true)
|
}.to change { membership.reload.muted }.from(false).to(true)
|
||||||
end
|
end
|
||||||
@ -93,10 +96,13 @@ RSpec.describe "Channel - Info - Settings page", type: :system do
|
|||||||
membership = channel_1.membership_for(current_user)
|
membership = channel_1.membership_for(current_user)
|
||||||
|
|
||||||
expect {
|
expect {
|
||||||
find(".channel-settings-view__desktop-notification-level-selector").click
|
select_kit =
|
||||||
find(
|
PageObjects::Components::SelectKit.new(
|
||||||
".channel-settings-view__desktop-notification-level-selector [data-name='Never']",
|
".-desktop-notification-level .channel-settings-view__selector",
|
||||||
).click
|
)
|
||||||
|
select_kit.expand
|
||||||
|
select_kit.select_row_by_name("Never")
|
||||||
|
|
||||||
expect(page).to have_content(I18n.t("js.chat.settings.saved"))
|
expect(page).to have_content(I18n.t("js.chat.settings.saved"))
|
||||||
}.to change { membership.reload.desktop_notification_level }.from("mention").to("never")
|
}.to change { membership.reload.desktop_notification_level }.from("mention").to("never")
|
||||||
end
|
end
|
||||||
@ -106,10 +112,13 @@ RSpec.describe "Channel - Info - Settings page", type: :system do
|
|||||||
membership = channel_1.membership_for(current_user)
|
membership = channel_1.membership_for(current_user)
|
||||||
|
|
||||||
expect {
|
expect {
|
||||||
find(".channel-settings-view__mobile-notification-level-selector").click
|
select_kit =
|
||||||
find(
|
PageObjects::Components::SelectKit.new(
|
||||||
".channel-settings-view__mobile-notification-level-selector [data-name='Never']",
|
".-mobile-notification-level .channel-settings-view__selector",
|
||||||
).click
|
)
|
||||||
|
select_kit.expand
|
||||||
|
select_kit.select_row_by_name("Never")
|
||||||
|
|
||||||
expect(page).to have_content(I18n.t("js.chat.settings.saved"))
|
expect(page).to have_content(I18n.t("js.chat.settings.saved"))
|
||||||
}.to change { membership.reload.mobile_notification_level }.from("mention").to("never")
|
}.to change { membership.reload.mobile_notification_level }.from("mention").to("never")
|
||||||
end
|
end
|
||||||
@ -133,9 +142,12 @@ RSpec.describe "Channel - Info - Settings page", type: :system do
|
|||||||
chat_page.visit_channel_settings(channel_1)
|
chat_page.visit_channel_settings(channel_1)
|
||||||
|
|
||||||
expect {
|
expect {
|
||||||
find(".channel-settings-view__auto-join-selector").click
|
select_kit =
|
||||||
find(".channel-settings-view__auto-join-selector [data-name='Yes']").click
|
PageObjects::Components::SelectKit.new(".-autojoin .channel-settings-view__selector")
|
||||||
|
select_kit.expand
|
||||||
|
select_kit.select_row_by_name("Yes")
|
||||||
find("#dialog-holder .btn-primary").click
|
find("#dialog-holder .btn-primary").click
|
||||||
|
|
||||||
expect(page).to have_content(I18n.t("js.chat.settings.saved"))
|
expect(page).to have_content(I18n.t("js.chat.settings.saved"))
|
||||||
}.to change { channel_1.reload.auto_join_users }.from(false).to(true)
|
}.to change { channel_1.reload.auto_join_users }.from(false).to(true)
|
||||||
end
|
end
|
||||||
@ -144,8 +156,13 @@ RSpec.describe "Channel - Info - Settings page", type: :system do
|
|||||||
chat_page.visit_channel_settings(channel_1)
|
chat_page.visit_channel_settings(channel_1)
|
||||||
|
|
||||||
expect {
|
expect {
|
||||||
find(".channel-settings-view__channel-wide-mentions-selector").click
|
select_kit =
|
||||||
find(".channel-settings-view__channel-wide-mentions-selector [data-name='No']").click
|
PageObjects::Components::SelectKit.new(
|
||||||
|
".-channel-wide-mentions .channel-settings-view__selector",
|
||||||
|
)
|
||||||
|
select_kit.expand
|
||||||
|
select_kit.select_row_by_name("No")
|
||||||
|
|
||||||
expect(page).to have_content(I18n.t("js.chat.settings.saved"))
|
expect(page).to have_content(I18n.t("js.chat.settings.saved"))
|
||||||
}.to change { channel_1.reload.allow_channel_wide_mentions }.from(true).to(false)
|
}.to change { channel_1.reload.allow_channel_wide_mentions }.from(true).to(false)
|
||||||
end
|
end
|
||||||
@ -160,6 +177,19 @@ RSpec.describe "Channel - Info - Settings page", type: :system do
|
|||||||
}.to change { channel_1.reload.status }.from("open").to("closed")
|
}.to change { channel_1.reload.status }.from("open").to("closed")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "can enable threading" do
|
||||||
|
SiteSetting.enable_experimental_chat_threaded_discussions = true
|
||||||
|
chat_page.visit_channel_settings(channel_1)
|
||||||
|
|
||||||
|
expect {
|
||||||
|
select_kit =
|
||||||
|
PageObjects::Components::SelectKit.new(".-threading .channel-settings-view__selector")
|
||||||
|
select_kit.expand
|
||||||
|
select_kit.select_row_by_name("Enabled")
|
||||||
|
expect(page).to have_content(I18n.t("js.chat.settings.saved"))
|
||||||
|
}.to change { channel_1.reload.threading_enabled }.from(false).to(true)
|
||||||
|
end
|
||||||
|
|
||||||
it "can delete channel" do
|
it "can delete channel" do
|
||||||
chat_page.visit_channel_settings(channel_1)
|
chat_page.visit_channel_settings(channel_1)
|
||||||
|
|
||||||
|
@ -32,6 +32,16 @@ RSpec.describe "Create channel", type: :system do
|
|||||||
expect(channel_modal).to have_create_hint(Group[:everyone].name)
|
expect(channel_modal).to have_create_hint(Group[:everyone].name)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "shows threading toggle" do
|
||||||
|
SiteSetting.enable_experimental_chat_threaded_discussions = true
|
||||||
|
|
||||||
|
chat_page.visit_browse
|
||||||
|
chat_page.new_channel_button.click
|
||||||
|
channel_modal.select_category(category_1)
|
||||||
|
|
||||||
|
expect(channel_modal).to have_threading_toggle
|
||||||
|
end
|
||||||
|
|
||||||
it "does not override channel name if that was already specified" do
|
it "does not override channel name if that was already specified" do
|
||||||
chat_page.visit_browse
|
chat_page.visit_browse
|
||||||
chat_page.new_channel_button.click
|
chat_page.new_channel_button.click
|
||||||
@ -138,7 +148,7 @@ RSpec.describe "Create channel", type: :system do
|
|||||||
context "for a public category" do
|
context "for a public category" do
|
||||||
before do
|
before do
|
||||||
channel_modal.select_category(category_1)
|
channel_modal.select_category(category_1)
|
||||||
find(".auto-join-channel__label").click
|
find(".-auto-join .create-channel__label").click
|
||||||
channel_modal.click_primary_button
|
channel_modal.click_primary_button
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -175,7 +185,7 @@ RSpec.describe "Create channel", type: :system do
|
|||||||
before do
|
before do
|
||||||
group_1.add(user_1)
|
group_1.add(user_1)
|
||||||
channel_modal.select_category(private_category)
|
channel_modal.select_category(private_category)
|
||||||
find(".auto-join-channel__label").click
|
find(".-auto-join .create-channel__label").click
|
||||||
channel_modal.click_primary_button
|
channel_modal.click_primary_button
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -9,17 +9,21 @@ module PageObjects
|
|||||||
end
|
end
|
||||||
|
|
||||||
def create_channel_hint
|
def create_channel_hint
|
||||||
find(".create-channel-hint")
|
find(".create-channel__hint")
|
||||||
end
|
end
|
||||||
|
|
||||||
def slug_input
|
def slug_input
|
||||||
find(".create-channel-slug-input")
|
find(".-slug .create-channel__input")
|
||||||
end
|
end
|
||||||
|
|
||||||
def has_create_hint?(content)
|
def has_create_hint?(content)
|
||||||
create_channel_hint.has_content?(content)
|
create_channel_hint.has_content?(content)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def has_threading_toggle?
|
||||||
|
has_selector?(".create-channel__control.-threading-toggle")
|
||||||
|
end
|
||||||
|
|
||||||
def fill_name(name)
|
def fill_name(name)
|
||||||
fill_in("channel-name", with: name)
|
fill_in("channel-name", with: name)
|
||||||
end
|
end
|
||||||
|
Loading…
Reference in New Issue
Block a user