diff --git a/app/assets/javascripts/discourse/app/helpers/category-badge.js b/app/assets/javascripts/discourse/app/helpers/category-badge.js
index b9e51674c91..ec697eecc63 100644
--- a/app/assets/javascripts/discourse/app/helpers/category-badge.js
+++ b/app/assets/javascripts/discourse/app/helpers/category-badge.js
@@ -1,12 +1,14 @@
import { categoryLinkHTML } from "discourse/helpers/category-link";
-import { registerUnbound } from "discourse-common/lib/helpers";
import { isPresent } from "@ember/utils";
+import { registerRawHelper } from "discourse-common/lib/helpers";
-registerUnbound("category-badge", function (cat, options) {
+registerRawHelper("category-badge", categoryBadge);
+
+export default function categoryBadge(cat, options = {}) {
return categoryLinkHTML(cat, {
hideParent: options.hideParent,
allowUncategorized: options.allowUncategorized,
categoryStyle: options.categoryStyle,
link: isPresent(options.link) ? options.link : false,
});
-});
+}
diff --git a/app/assets/javascripts/discourse/app/helpers/replace-emoji.js b/app/assets/javascripts/discourse/app/helpers/replace-emoji.js
index 81d78a3a1f4..13c1f7ea193 100644
--- a/app/assets/javascripts/discourse/app/helpers/replace-emoji.js
+++ b/app/assets/javascripts/discourse/app/helpers/replace-emoji.js
@@ -1,9 +1,11 @@
import { emojiUnescape } from "discourse/lib/text";
import { htmlSafe, isHTMLSafe } from "@ember/template";
-import { registerUnbound } from "discourse-common/lib/helpers";
import { escapeExpression } from "discourse/lib/utilities";
+import { registerRawHelper } from "discourse-common/lib/helpers";
-registerUnbound("replace-emoji", (text, options) => {
+registerRawHelper("replace-emoji", replaceEmoji);
+
+export default function replaceEmoji(text, options) {
text = isHTMLSafe(text) ? text.toString() : escapeExpression(text);
return htmlSafe(emojiUnescape(text, options));
-});
+}
diff --git a/app/assets/javascripts/float-kit/addon/lib/constants.js b/app/assets/javascripts/float-kit/addon/lib/constants.js
index 64a1a39c25e..6590e1820d8 100644
--- a/app/assets/javascripts/float-kit/addon/lib/constants.js
+++ b/app/assets/javascripts/float-kit/addon/lib/constants.js
@@ -70,7 +70,7 @@ import DDefaultToast from "float-kit/components/d-default-toast";
export const TOAST = {
options: {
autoClose: true,
- duration: 10000,
+ duration: 3000,
component: DDefaultToast,
},
};
diff --git a/plugins/chat/assets/javascripts/discourse/chat-route-map.js b/plugins/chat/assets/javascripts/discourse/chat-route-map.js
index 7237e535014..2131b6b82cd 100644
--- a/plugins/chat/assets/javascripts/discourse/chat-route-map.js
+++ b/plugins/chat/assets/javascripts/discourse/chat-route-map.js
@@ -12,7 +12,6 @@ export default function () {
"channel.info",
{ path: "/c/:channelTitle/:channelId/info" },
function () {
- this.route("about", { path: "/about" });
this.route("members", { path: "/members" });
this.route("settings", { path: "/settings" });
}
diff --git a/plugins/chat/assets/javascripts/discourse/components/chat-channel-about-view.hbs b/plugins/chat/assets/javascripts/discourse/components/chat-channel-about-view.hbs
deleted file mode 100644
index 23046d405b3..00000000000
--- a/plugins/chat/assets/javascripts/discourse/components/chat-channel-about-view.hbs
+++ /dev/null
@@ -1,93 +0,0 @@
-{{#if this.channel.isCategoryChannel}}
-
+ {{! template-lint-disable modifier-name-case }}
+
+ {{#if @icons.left}}
+ {{icon @icons.left class="-left"}}
+ {{/if}}
+
+
+
+ {{yield}}
+
+ {{#if @icons.right}}
+ {{icon @icons.right class="-right"}}
+ {{/if}}
+
+
+
+ @tracked isFocused = false;
+
+ focusState = modifier((element) => {
+ const focusInHandler = () => {
+ this.isFocused = true;
+ };
+ const focusOutHandler = () => {
+ this.isFocused = false;
+ };
+
+ element.addEventListener("focusin", focusInHandler);
+ element.addEventListener("focusout", focusOutHandler);
+
+ return () => {
+ element.removeEventListener("focusin", focusInHandler);
+ element.removeEventListener("focusout", focusOutHandler);
+ };
+ });
+}
diff --git a/plugins/chat/assets/javascripts/discourse/components/dc-filter-input.hbs b/plugins/chat/assets/javascripts/discourse/components/dc-filter-input.hbs
deleted file mode 100644
index a3d465fe24e..00000000000
--- a/plugins/chat/assets/javascripts/discourse/components/dc-filter-input.hbs
+++ /dev/null
@@ -1,26 +0,0 @@
-
- {{#if @icons.left}}
- {{d-icon @icons.left class="-left"}}
- {{/if}}
-
-
-
- {{yield}}
-
- {{#if @icons.right}}
- {{d-icon @icons.right class="-right"}}
- {{/if}}
-
\ No newline at end of file
diff --git a/plugins/chat/assets/javascripts/discourse/components/dc-filter-input.js b/plugins/chat/assets/javascripts/discourse/components/dc-filter-input.js
deleted file mode 100644
index 60b7b82ea4f..00000000000
--- a/plugins/chat/assets/javascripts/discourse/components/dc-filter-input.js
+++ /dev/null
@@ -1,3 +0,0 @@
-import Component from "@glimmer/component";
-
-export default class DcFilterInput extends Component {}
diff --git a/plugins/chat/assets/javascripts/discourse/controllers/chat-channel-info-about.js b/plugins/chat/assets/javascripts/discourse/controllers/chat-channel-info-about.js
deleted file mode 100644
index 8748478788f..00000000000
--- a/plugins/chat/assets/javascripts/discourse/controllers/chat-channel-info-about.js
+++ /dev/null
@@ -1,26 +0,0 @@
-import Controller from "@ember/controller";
-import { action } from "@ember/object";
-import ModalFunctionality from "discourse/mixins/modal-functionality";
-import { inject as service } from "@ember/service";
-import ChatModalEditChannelDescription from "discourse/plugins/chat/discourse/components/chat/modal/edit-channel-description";
-import ChatModalEditChannelName from "discourse/plugins/chat/discourse/components/chat/modal/edit-channel-name";
-
-export default class ChatChannelInfoAboutController extends Controller.extend(
- ModalFunctionality
-) {
- @service modal;
-
- @action
- onEditChatChannelName() {
- return this.modal.show(ChatModalEditChannelName, {
- model: this.model,
- });
- }
-
- @action
- onEditChatChannelDescription() {
- return this.modal.show(ChatModalEditChannelDescription, {
- model: this.model,
- });
- }
-}
diff --git a/plugins/chat/assets/javascripts/discourse/controllers/chat-channel-info-members.js b/plugins/chat/assets/javascripts/discourse/controllers/chat-channel-info-members.js
deleted file mode 100644
index 48e3c615581..00000000000
--- a/plugins/chat/assets/javascripts/discourse/controllers/chat-channel-info-members.js
+++ /dev/null
@@ -1,3 +0,0 @@
-import Controller from "@ember/controller";
-
-export default class ChatChannelInfoMembersController extends Controller {}
diff --git a/plugins/chat/assets/javascripts/discourse/controllers/chat-channel-info-settings.js b/plugins/chat/assets/javascripts/discourse/controllers/chat-channel-info-settings.js
deleted file mode 100644
index a70d62d1ea9..00000000000
--- a/plugins/chat/assets/javascripts/discourse/controllers/chat-channel-info-settings.js
+++ /dev/null
@@ -1,3 +0,0 @@
-import Controller from "@ember/controller";
-
-export default class ChatChannelInfoSettingsController extends Controller {}
diff --git a/plugins/chat/assets/javascripts/discourse/controllers/chat-channel-info.js b/plugins/chat/assets/javascripts/discourse/controllers/chat-channel-info.js
deleted file mode 100644
index 65c132080d9..00000000000
--- a/plugins/chat/assets/javascripts/discourse/controllers/chat-channel-info.js
+++ /dev/null
@@ -1,34 +0,0 @@
-import Controller from "@ember/controller";
-import { inject as service } from "@ember/service";
-import { reads } from "@ember/object/computed";
-import { computed } from "@ember/object";
-
-export default class ChatChannelInfoIndexController extends Controller {
- @service router;
- @service chat;
- @service chatChannelInfoRouteOriginManager;
-
- @reads("router.currentRoute.localName") tab;
-
- @computed("model.{membershipsCount,status,currentUserMembership.following}")
- get tabs() {
- const tabs = [];
-
- if (!this.model.isDirectMessageChannel) {
- tabs.push("about");
- }
-
- if (this.model.isOpen && this.model.membershipsCount >= 1) {
- tabs.push("members");
- }
-
- if (
- this.currentUser?.staff ||
- this.model.currentUserMembership?.following
- ) {
- tabs.push("settings");
- }
-
- return tabs;
- }
-}
diff --git a/plugins/chat/assets/javascripts/discourse/lib/collection.js b/plugins/chat/assets/javascripts/discourse/lib/collection.js
index e472d45bffe..08014429e6b 100644
--- a/plugins/chat/assets/javascripts/discourse/lib/collection.js
+++ b/plugins/chat/assets/javascripts/discourse/lib/collection.js
@@ -12,9 +12,10 @@ export default class Collection {
@tracked loading = false;
@tracked fetchedOnce = false;
- constructor(resourceURL, handler) {
+ constructor(resourceURL, handler, params = {}) {
this._resourceURL = resourceURL;
this._handler = handler;
+ this._params = params;
this._fetchedAll = false;
}
@@ -94,6 +95,6 @@ export default class Collection {
}
#fetch(url) {
- return ajax(url, { type: "GET" });
+ return ajax(url, { type: "GET", data: this._params });
}
}
diff --git a/plugins/chat/assets/javascripts/discourse/routes/chat-channel-info-about.js b/plugins/chat/assets/javascripts/discourse/routes/chat-channel-info-about.js
deleted file mode 100644
index 9bb3d7b81b0..00000000000
--- a/plugins/chat/assets/javascripts/discourse/routes/chat-channel-info-about.js
+++ /dev/null
@@ -1,12 +0,0 @@
-import DiscourseRoute from "discourse/routes/discourse";
-import { inject as service } from "@ember/service";
-
-export default class ChatChannelInfoAboutRoute extends DiscourseRoute {
- @service router;
-
- afterModel(model) {
- if (model.isDirectMessageChannel) {
- this.router.replaceWith("chat.channel.info.index");
- }
- }
-}
diff --git a/plugins/chat/assets/javascripts/discourse/routes/chat-channel-info-index.js b/plugins/chat/assets/javascripts/discourse/routes/chat-channel-info-index.js
index 03258bae148..34ffcf2343e 100644
--- a/plugins/chat/assets/javascripts/discourse/routes/chat-channel-info-index.js
+++ b/plugins/chat/assets/javascripts/discourse/routes/chat-channel-info-index.js
@@ -4,15 +4,7 @@ import { inject as service } from "@ember/service";
export default class ChatChannelInfoIndexRoute extends DiscourseRoute {
@service router;
- afterModel(model) {
- if (model.isDirectMessageChannel) {
- if (model.isOpen && model.membershipsCount >= 1) {
- this.router.replaceWith("chat.channel.info.members");
- } else {
- this.router.replaceWith("chat.channel.info.settings");
- }
- } else {
- this.router.replaceWith("chat.channel.info.about");
- }
+ afterModel() {
+ this.router.replaceWith("chat.channel.info.settings");
}
}
diff --git a/plugins/chat/assets/javascripts/discourse/routes/chat-channel-info-members.js b/plugins/chat/assets/javascripts/discourse/routes/chat-channel-info-members.js
index 6260e3f1a65..e6912480514 100644
--- a/plugins/chat/assets/javascripts/discourse/routes/chat-channel-info-members.js
+++ b/plugins/chat/assets/javascripts/discourse/routes/chat-channel-info-members.js
@@ -5,12 +5,8 @@ export default class ChatChannelInfoMembersRoute extends DiscourseRoute {
@service router;
afterModel(model) {
- if (!model.isOpen) {
+ if (!model.isOpen || model.membershipsCount < 1) {
return this.router.replaceWith("chat.channel.info.settings");
}
-
- if (model.membershipsCount < 1) {
- return this.router.replaceWith("chat.channel.info");
- }
}
}
diff --git a/plugins/chat/assets/javascripts/discourse/routes/chat-channel-info-settings.js b/plugins/chat/assets/javascripts/discourse/routes/chat-channel-info-settings.js
deleted file mode 100644
index 8468b04492d..00000000000
--- a/plugins/chat/assets/javascripts/discourse/routes/chat-channel-info-settings.js
+++ /dev/null
@@ -1,13 +0,0 @@
-import DiscourseRoute from "discourse/routes/discourse";
-import { inject as service } from "@ember/service";
-
-export default class ChatChannelInfoSettingsRoute extends DiscourseRoute {
- @service router;
- @service currentUser;
-
- afterModel(model) {
- if (!this.currentUser?.staff && !model.currentUserMembership?.following) {
- this.router.replaceWith("chat.channel.info");
- }
- }
-}
diff --git a/plugins/chat/assets/javascripts/discourse/services/chat-api.js b/plugins/chat/assets/javascripts/discourse/services/chat-api.js
index daae4cc8b19..f4ab3c79068 100644
--- a/plugins/chat/assets/javascripts/discourse/services/chat-api.js
+++ b/plugins/chat/assets/javascripts/discourse/services/chat-api.js
@@ -233,14 +233,15 @@ export default class ChatApi extends Service {
* @param {number} channelId - The ID of the channel.
* @returns {Collection}
*/
- listChannelMemberships(channelId) {
+ listChannelMemberships(channelId, params = {}) {
return new Collection(
`${this.#basePath}/channels/${channelId}/memberships`,
(response) => {
return response.memberships.map((membership) =>
UserChatChannelMembership.create(membership)
);
- }
+ },
+ params
);
}
diff --git a/plugins/chat/assets/javascripts/discourse/services/chat-channels-manager.js b/plugins/chat/assets/javascripts/discourse/services/chat-channels-manager.js
index 882353e6d45..7a6f9d8df80 100644
--- a/plugins/chat/assets/javascripts/discourse/services/chat-channels-manager.js
+++ b/plugins/chat/assets/javascripts/discourse/services/chat-channels-manager.js
@@ -18,6 +18,7 @@ export default class ChatChannelsManager extends Service {
@service chatSubscriptionsManager;
@service chatApi;
@service currentUser;
+ @service router;
@tracked _cached = new TrackedObject();
async find(id, options = { fetchIfNotFound: true }) {
@@ -131,12 +132,12 @@ export default class ChatChannelsManager extends Service {
}
async #find(id) {
- return this.chatApi
- .channel(id)
- .catch(popupAjaxError)
- .then((result) => {
- return this.store(result.channel);
- });
+ try {
+ const result = await this.chatApi.channel(id);
+ return this.store(result.channel);
+ } catch (error) {
+ popupAjaxError(error);
+ }
}
#cache(channel) {
diff --git a/plugins/chat/assets/javascripts/discourse/services/chat-guardian.js b/plugins/chat/assets/javascripts/discourse/services/chat-guardian.js
index 791b06938e6..7411643bdaf 100644
--- a/plugins/chat/assets/javascripts/discourse/services/chat-guardian.js
+++ b/plugins/chat/assets/javascripts/discourse/services/chat-guardian.js
@@ -1,6 +1,9 @@
-import Service from "@ember/service";
+import Service, { inject as service } from "@ember/service";
export default class ChatGuardian extends Service {
+ @service currentUser;
+ @service siteSettings;
+
canEditChatChannel() {
return this.canUseChat() && this.currentUser.staff;
}
diff --git a/plugins/chat/assets/javascripts/discourse/templates/chat-channel-info-about.hbs b/plugins/chat/assets/javascripts/discourse/templates/chat-channel-info-about.hbs
deleted file mode 100644
index 83de81608a8..00000000000
--- a/plugins/chat/assets/javascripts/discourse/templates/chat-channel-info-about.hbs
+++ /dev/null
@@ -1,5 +0,0 @@
-
\ No newline at end of file
diff --git a/plugins/chat/assets/javascripts/discourse/templates/chat-channel-info-members.hbs b/plugins/chat/assets/javascripts/discourse/templates/chat-channel-info-members.hbs
index 50f2aa56629..3294012102c 100644
--- a/plugins/chat/assets/javascripts/discourse/templates/chat-channel-info-members.hbs
+++ b/plugins/chat/assets/javascripts/discourse/templates/chat-channel-info-members.hbs
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/plugins/chat/assets/javascripts/discourse/templates/chat-channel-info-settings.hbs b/plugins/chat/assets/javascripts/discourse/templates/chat-channel-info-settings.hbs
index 633f0350277..2aac01fe3da 100644
--- a/plugins/chat/assets/javascripts/discourse/templates/chat-channel-info-settings.hbs
+++ b/plugins/chat/assets/javascripts/discourse/templates/chat-channel-info-settings.hbs
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/plugins/chat/assets/javascripts/discourse/templates/chat-channel-info.hbs b/plugins/chat/assets/javascripts/discourse/templates/chat-channel-info.hbs
index e390f0a194c..660315b5925 100644
--- a/plugins/chat/assets/javascripts/discourse/templates/chat-channel-info.hbs
+++ b/plugins/chat/assets/javascripts/discourse/templates/chat-channel-info.hbs
@@ -1,65 +1 @@
-
-
-
-
-
-
-
- {{#each this.tabs as |tab|}}
- -
-
- {{i18n (concat "chat.channel_info.tabs." tab)}}
- {{#if (eq tab "members")}}
-
- ({{this.model.membershipsCount}})
-
- {{/if}}
-
-
- {{/each}}
-
-
-
- {{outlet}}
-
-
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/plugins/chat/assets/stylesheets/common/chat-channel-info.scss b/plugins/chat/assets/stylesheets/common/chat-channel-info.scss
index be5dee75b81..3993019c0d6 100644
--- a/plugins/chat/assets/stylesheets/common/chat-channel-info.scss
+++ b/plugins/chat/assets/stylesheets/common/chat-channel-info.scss
@@ -1,11 +1,19 @@
-.channel-info {
+.chat-channel-info {
display: flex;
flex-direction: column;
height: 100%;
+ padding: 1rem;
+
+ &__nav {
+ .nav-pills {
+ margin: 0;
+ padding-bottom: 1rem;
+ }
+ }
}
// Info header
-.channel-info-header {
+.chat-channel-info-header {
display: flex;
justify-content: space-between;
align-items: flex-start;
@@ -13,129 +21,7 @@
box-sizing: border-box;
}
-.channel-info-header__title {
+.chat-channel-info-header__title {
font-size: var(--font-up-2);
margin: 0;
}
-
-// About view
-.channel-info-about-view__title-input {
- width: 100%;
-}
-
-.channel-info-about-view__description-input {
- height: 150px;
- width: 100%;
-}
-
-.channel-info-about-view__description__helper-text {
- color: var(--primary-medium);
-}
-
-.channel-info-about-view__slug {
- color: var(--primary-medium);
- font-size: var(--font-down-2);
-}
-
-.channel-settings-view__selector {
- 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 {
- .d-icon {
- color: var(--danger);
- }
-}
-
-// Members list
-.chat-tabs__memberships-count {
- margin-left: 0.25em;
-}
-
-.channel-members-view-wrapper {
- display: flex;
- flex-direction: column;
- height: 100%;
- box-sizing: border-box;
- padding: 0 1rem;
-}
-
-.channel-members-view__search-input-container {
- display: flex;
- align-items: center;
- border: 1px solid var(--primary-medium);
-
- &.is-focused {
- border: 1px solid var(--tertiary);
- }
-
- .d-icon {
- padding: 0.5rem;
- color: var(--primary-medium);
- }
-}
-
-input.channel-members-view__search-input {
- border: 0;
- margin: 0;
- outline: 0;
- width: 100%;
-
- &:focus {
- border: 0;
- outline: 0;
- }
-}
-
-.channel-members-view__status {
- display: flex;
- align-items: center;
-}
-
-.channel-members-view__list-container {
- display: flex;
- flex-direction: column;
- margin-top: 1em;
- box-sizing: border-box;
-}
-
-.channel-members-view__list-item {
- display: flex;
- align-items: center;
- padding: 0.5rem 0 0.5rem 1px;
-
- &:not(:last-child) {
- border-bottom: 1px solid var(--primary-low);
- }
-
- .chat-user-avatar {
- margin-right: 0.5rem;
- }
-}
-
-// Channel info edit name and slug modal
-.chat-channel-edit-name-slug-modal {
- .modal-inner-container {
- width: 300px;
- }
-
- &__name-input,
- &__slug-input {
- display: flex;
- margin: 0;
- width: 100%;
- }
-}
-
-.chat-channel-edit-name-slug-modal__description {
- display: flex;
- padding: 0.5rem 0;
- color: var(--primary-medium);
-}
diff --git a/plugins/chat/assets/stylesheets/common/chat-channel-members.scss b/plugins/chat/assets/stylesheets/common/chat-channel-members.scss
new file mode 100644
index 00000000000..40a07573bce
--- /dev/null
+++ b/plugins/chat/assets/stylesheets/common/chat-channel-members.scss
@@ -0,0 +1,32 @@
+.chat-channel-members {
+ width: 50%;
+ min-width: 320px;
+
+ &__filter {
+ margin-bottom: 1rem;
+ }
+
+ &__list {
+ display: flex;
+ margin: 0;
+ flex-direction: column;
+ gap: 0.5rem;
+
+ &-item {
+ display: flex;
+ gap: 0.5rem;
+ list-style: none;
+ border-bottom: 1px solid var(--primary-low);
+ height: 42px;
+ align-items: center;
+
+ &.-no-results {
+ box-sizing: border-box;
+ }
+
+ &:last-child {
+ border-bottom: none;
+ }
+ }
+ }
+}
diff --git a/plugins/chat/assets/stylesheets/common/chat-channel-settings-saved-indicator.scss b/plugins/chat/assets/stylesheets/common/chat-channel-settings-saved-indicator.scss
deleted file mode 100644
index e28129f3e17..00000000000
--- a/plugins/chat/assets/stylesheets/common/chat-channel-settings-saved-indicator.scss
+++ /dev/null
@@ -1,9 +0,0 @@
-.chat-channel-settings-saved-indicator {
- padding-left: 0.5rem;
- color: var(--success);
- font-weight: normal;
-
- .d-icon-check {
- margin-right: 0.25rem;
- }
-}
diff --git a/plugins/chat/assets/stylesheets/common/chat-channel-settings.scss b/plugins/chat/assets/stylesheets/common/chat-channel-settings.scss
new file mode 100644
index 00000000000..86023946e05
--- /dev/null
+++ b/plugins/chat/assets/stylesheets/common/chat-channel-settings.scss
@@ -0,0 +1,18 @@
+.chat-channel-settings {
+ width: 50%;
+ min-width: 320px;
+
+ .chat-channel-settings__slug {
+ max-width: 250px;
+ @include ellipsis;
+ }
+
+ // category badge margin reset
+ .badge-wrapper.bullet {
+ margin-right: 0;
+ }
+
+ .chat-retention-reminder-text {
+ color: var(--primary-medium);
+ }
+}
diff --git a/plugins/chat/assets/stylesheets/common/chat-form.scss b/plugins/chat/assets/stylesheets/common/chat-form.scss
index 24e44dc5d84..4071798448a 100644
--- a/plugins/chat/assets/stylesheets/common/chat-form.scss
+++ b/plugins/chat/assets/stylesheets/common/chat-form.scss
@@ -1,62 +1,86 @@
-.chat-form__section {
- margin: 1.5rem 1rem;
-
- &:first-child {
- margin-top: 0;
- }
-
- &:last-child {
- margin-bottom: 0;
- border-bottom: none;
- }
-}
-.chat-form__section-admin-title {
- margin-inline: 1rem;
- padding-top: 1rem;
- border-top: 1px solid var(--primary-low);
-}
-
-.chat-form__field {
- margin-bottom: 1rem;
-
- &:last-child {
- margin-bottom: 0;
- }
-}
-
-.chat-form__description {
- margin-top: 3px;
- color: var(--primary-medium);
- font-size: var(--font-down-1);
-}
-
-.chat-form__btn {
- border: 0;
- background: none;
- padding: 0.25rem 0;
- margin: 0;
-}
-
-.chat-form__label {
- font-weight: 700;
+.chat-form {
display: flex;
- align-items: center;
+ flex-direction: column;
}
-.chat-form__label-actions {
- margin-left: auto;
+.chat-form__row {
+ &.-separator {
+ border-bottom: 1px solid var(--primary-low);
+ }
+}
- .btn-text {
- color: var(--tertiary);
+.chat-form__section {
+ display: flex;
+ flex-direction: column;
+ width: 100%;
+
+ & + .chat-form__section {
+ margin-top: 1rem;
+ }
+
+ &-title {
+ font-weight: 700;
+ font-size: var(--font-down-1);
+ color: var(--primary-medium);
+ }
+
+ &-title + &-content {
+ margin-top: 0.25rem;
+ }
+
+ &-content {
+ background: var(--primary-very-low);
+ gap: 1rem;
+ display: flex;
+ padding: 1rem;
+ flex-direction: column;
+ }
+}
+
+.chat-form__row {
+ display: flex;
+ width: 100%;
+
+ // background: green;
+ flex-direction: column;
+ justify-content: center;
+
+ label,
+ .d-toggle-switch__checkbox-slider {
+ margin: 0;
+ }
+
+ &-action {
+ .chat-form__btn:first-child {
+ padding-left: 0;
+ }
+ }
+
+ &-label + &-action {
+ margin-left: auto;
+ }
+
+ &.-link {
+ color: var(--primary);
+
+ .d-icon {
+ color: var(--primary-medium);
+ }
+ }
+
+ &-content {
+ display: flex;
+ flex-direction: row;
+ justify-content: space-between;
+ align-items: center;
+ min-height: 40px;
+ gap: 0.25rem;
+ }
+
+ &-description {
+ display: flex;
+ padding-top: 3px;
+ color: var(--primary-medium);
font-size: var(--font-down-1);
}
}
-
-.chat-retention-info {
- margin-top: 2rem;
- color: var(--primary-high);
-
- .d-icon {
- margin-right: 0.5em;
- }
-}
diff --git a/plugins/chat/assets/stylesheets/common/index.scss b/plugins/chat/assets/stylesheets/common/index.scss
index d9ab114867a..220f88a4cbf 100644
--- a/plugins/chat/assets/stylesheets/common/index.scss
+++ b/plugins/chat/assets/stylesheets/common/index.scss
@@ -8,7 +8,6 @@
@import "chat-channel-card";
@import "chat-channel-info";
@import "chat-channel-preview-card";
-@import "chat-channel-settings-saved-indicator";
@import "chat-channel-title";
@import "chat-composer-dropdown";
@import "chat-composer-upload";
@@ -64,3 +63,5 @@
@import "chat-modal-move-message-to-channel";
@import "chat-scroll-to-bottom";
@import "chat-channel-row";
+@import "chat-channel-members";
+@import "chat-channel-settings";
diff --git a/plugins/chat/assets/stylesheets/mobile/chat-channel-info.scss b/plugins/chat/assets/stylesheets/mobile/chat-channel-info.scss
deleted file mode 100644
index e69de29bb2d..00000000000
diff --git a/plugins/chat/assets/stylesheets/mobile/chat-channel-members.scss b/plugins/chat/assets/stylesheets/mobile/chat-channel-members.scss
new file mode 100644
index 00000000000..2e9eaadc263
--- /dev/null
+++ b/plugins/chat/assets/stylesheets/mobile/chat-channel-members.scss
@@ -0,0 +1,3 @@
+.chat-channel-members {
+ width: 100%;
+}
diff --git a/plugins/chat/assets/stylesheets/mobile/chat-channel-settings.scss b/plugins/chat/assets/stylesheets/mobile/chat-channel-settings.scss
new file mode 100644
index 00000000000..871658cf968
--- /dev/null
+++ b/plugins/chat/assets/stylesheets/mobile/chat-channel-settings.scss
@@ -0,0 +1,3 @@
+.chat-channel-settings {
+ width: 100%;
+}
diff --git a/plugins/chat/assets/stylesheets/mobile/index.scss b/plugins/chat/assets/stylesheets/mobile/index.scss
index 833388c5a50..7e3065003e4 100644
--- a/plugins/chat/assets/stylesheets/mobile/index.scss
+++ b/plugins/chat/assets/stylesheets/mobile/index.scss
@@ -1,5 +1,4 @@
@import "base-mobile";
-@import "chat-channel-info";
@import "chat-channel";
@import "chat-composer";
@import "chat-index";
@@ -15,3 +14,5 @@
@import "chat-message-thread-indicator";
@import "chat-message-creator";
@import "chat-channel-row";
+@import "chat-channel-members";
+@import "chat-channel-settings";
diff --git a/plugins/chat/config/locales/client.en.yml b/plugins/chat/config/locales/client.en.yml
index 7b3e6828692..72358feed53 100644
--- a/plugins/chat/config/locales/client.en.yml
+++ b/plugins/chat/config/locales/client.en.yml
@@ -320,7 +320,6 @@ en:
back_to_all_channels: "All channels"
back_to_channel: "Back"
tabs:
- about: About
members: Members
settings: Settings
@@ -462,6 +461,11 @@ en:
saved: "Saved"
unfollow: "Leave"
admin_title: "Admin"
+ settings_title: "Settings"
+ info_title: "Channel info"
+ category_label: "Category"
+ history_label: "History"
+ members_label: "Members"
admin:
title: "Chat"
@@ -538,14 +542,14 @@ en:
other: "%{commaSeparatedUsernames} and %{count} others are typing"
retention_reminders:
- public_none: "Channel history is retained indefinitely."
+ public_none: "indefinitely"
public:
- one: "Channel history is retained for %{count} day."
- other: "Channel history is retained for %{count} days."
- dm_none: "Personal chat history is retained indefinitely."
+ one: "%{count} day"
+ other: "%{count} days"
+ dm_none: "indefinitely"
dm:
- one: "Personal chat history is retained for %{count} day."
- other: "Personal chat history is retained for %{count} days."
+ one: "%{count} day"
+ other: "%{count} days"
flags:
off_topic: "This message is not relevant to the current discussion as defined by the channel title, and should probably be moved elsewhere."
diff --git a/plugins/chat/spec/system/channel_about_page_spec.rb b/plugins/chat/spec/system/channel_about_page_spec.rb
deleted file mode 100644
index 550fa4c3ee4..00000000000
--- a/plugins/chat/spec/system/channel_about_page_spec.rb
+++ /dev/null
@@ -1,138 +0,0 @@
-# frozen_string_literal: true
-
-RSpec.describe "Channel - Info - About page", type: :system do
- fab!(:channel_1) { Fabricate(:category_channel) }
-
- let(:chat_page) { PageObjects::Pages::Chat.new }
- let(:chat_channel_about_page) { PageObjects::Pages::ChatChannelAbout.new }
-
- before { chat_system_bootstrap }
-
- context "as regular user" do
- fab!(:current_user) { Fabricate(:user) }
-
- before { sign_in(current_user) }
-
- it "shows channel info" do
- chat_page.visit_channel_about(channel_1)
-
- expect(page.find(".category-name")).to have_content(channel_1.chatable.name)
- expect(page.find(".channel-info-about-view__name")).to have_content(channel_1.title)
- expect(page.find(".channel-info-about-view__slug")).to have_content(channel_1.slug)
- end
-
- it "escapes channel title" do
- channel_1.update!(name: "")
- chat_page.visit_channel_about(channel_1)
-
- expect(page.find(".channel-info-about-view__name")["innerHTML"].strip).to eq(
- "<script>alert('hello')</script>",
- )
- expect(page.find(".chat-channel-title__name")["innerHTML"].strip).to eq(
- "<script>alert('hello')</script>",
- )
- end
-
- it "can’t edit name or slug" do
- chat_page.visit_channel_about(channel_1)
-
- expect(page).to have_no_selector(".edit-name-slug-btn")
- end
-
- it "can’t edit description" do
- chat_page.visit_channel_about(channel_1)
-
- expect(page).to have_no_selector(".edit-description-btn")
- end
-
- context "as a member" do
- before { channel_1.add(current_user) }
-
- it "can leave channel" do
- chat_page.visit_channel_about(channel_1)
- membership = channel_1.membership_for(current_user)
-
- expect {
- click_button(I18n.t("js.chat.channel_settings.leave_channel"))
- expect(page).to have_content(I18n.t("js.chat.channel_settings.join_channel"))
- }.to change { membership.reload.following }.from(true).to(false)
- end
- end
-
- context "as not a member" do
- it "can join channel" do
- chat_page.visit_channel_about(channel_1)
-
- expect {
- click_button(I18n.t("js.chat.channel_settings.join_channel"))
- expect(page).to have_content(I18n.t("js.chat.channel_settings.leave_channel"))
- }.to change {
- Chat::UserChatChannelMembership.where(user_id: current_user.id, following: true).count
- }.by(1)
- end
- end
- end
-
- context "as admin" do
- fab!(:current_user) { Fabricate(:admin) }
-
- before { sign_in(current_user) }
-
- it "can edit name" do
- chat_page.visit_channel_about(channel_1)
-
- edit_modal = chat_channel_about_page.open_edit_modal
-
- expect(edit_modal).to have_name_input(channel_1.title)
-
- name = "A new name"
-
- edit_modal.fill_and_save_name(name)
-
- expect(chat_channel_about_page).to have_name(name)
- end
-
- it "can edit description" do
- chat_page.visit_channel_about(channel_1)
- find(".edit-description-btn").click
-
- expect(page).to have_selector(
- ".chat-modal-edit-channel-description__description-input",
- text: channel_1.description,
- )
-
- description = "A new description"
- find(".chat-modal-edit-channel-description__description-input").fill_in(with: description)
- find(".create").click
-
- expect(page).to have_content(description)
- end
-
- it "can edit slug" do
- chat_page.visit_channel_about(channel_1)
- edit_modal = chat_channel_about_page.open_edit_modal
-
- slug = "gonzo-slug"
-
- expect(edit_modal).to have_slug_input(channel_1.slug)
-
- edit_modal.fill_and_save_slug(slug)
-
- expect(chat_channel_about_page).to have_slug(slug)
- end
-
- it "can clear the slug to use the autogenerated version based on the name" do
- channel_1.update!(name: "test channel")
- chat_page.visit_channel_about(channel_1)
- edit_modal = chat_channel_about_page.open_edit_modal
-
- expect(edit_modal).to have_slug_input(channel_1.slug)
-
- edit_modal.fill_in_slug_input("")
- edit_modal.wait_for_auto_generated_slug
- edit_modal.save_changes
-
- expect(chat_channel_about_page).to have_slug("test-channel")
- end
- end
-end
diff --git a/plugins/chat/spec/system/channel_info_pages_spec.rb b/plugins/chat/spec/system/channel_info_pages_spec.rb
deleted file mode 100644
index 0b53d1e0f05..00000000000
--- a/plugins/chat/spec/system/channel_info_pages_spec.rb
+++ /dev/null
@@ -1,38 +0,0 @@
-# frozen_string_literal: true
-
-RSpec.describe "Info pages", type: :system do
- let(:chat_page) { PageObjects::Pages::Chat.new }
- let(:channel) { PageObjects::Pages::ChatChannel.new }
- fab!(:current_user) { Fabricate(:user) }
- fab!(:channel_1) { Fabricate(:chat_channel) }
-
- before do
- chat_system_bootstrap
- channel_1.add(current_user)
- sign_in(current_user)
- end
-
- context "when visiting from browse page" do
- context "when clicking back button" do
- it "redirects to browse page" do
- chat_page.visit_browse
- find(".chat-channel-card__setting").click
- find(".chat-full-page-header__back-btn").click
-
- expect(page).to have_current_path("/chat/browse/open")
- end
- end
- end
-
- context "when visiting from channel page" do
- context "when clicking back button" do
- it "redirects to channel page" do
- chat_page.visit_channel(channel_1)
- find(".chat-channel-title-wrapper").click
- find(".chat-full-page-header__back-btn").click
-
- expect(page).to have_current_path(chat.channel_path(channel_1.slug, channel_1.id))
- end
- end
- end
-end
diff --git a/plugins/chat/spec/system/channel_members_page_spec.rb b/plugins/chat/spec/system/channel_members_page_spec.rb
index becfd2812f7..8c7b3c9eae0 100644
--- a/plugins/chat/spec/system/channel_members_page_spec.rb
+++ b/plugins/chat/spec/system/channel_members_page_spec.rb
@@ -14,7 +14,7 @@ RSpec.describe "Channel - Info - Members page", type: :system do
context "as unauthorized user" do
before { SiteSetting.chat_allowed_groups = Fabricate(:group).id }
- it "can’t see channel members" do
+ it "can't see channel members" do
chat_page.visit_channel_members(channel_1)
expect(page).to have_current_path("/latest")
@@ -23,10 +23,10 @@ RSpec.describe "Channel - Info - Members page", type: :system do
context "as authorized user" do
context "with no members" do
- it "redirects to about page" do
+ it "redirects to settings page" do
chat_page.visit_channel_members(channel_1)
- expect(page).to have_current_path("/chat/c/#{channel_1.slug}/#{channel_1.id}/info/about")
+ expect(page).to have_current_path("/chat/c/#{channel_1.slug}/#{channel_1.id}/info/settings")
end
end
@@ -44,15 +44,15 @@ RSpec.describe "Channel - Info - Members page", type: :system do
chat_page.visit_channel_members(channel_1)
- expect(page).to have_selector(".channel-members-view__list-item", count: 50, wait: 15)
+ expect(page).to have_selector(".chat-channel-members__list-item", count: 60)
- scroll_to(find(".channel-members-view__list-item:nth-child(50)"))
+ scroll_to(find(".chat-channel-members__list-item:nth-child(50)"))
- expect(page).to have_selector(".channel-members-view__list-item", count: 100, wait: 15)
+ expect(page).to have_selector(".chat-channel-members__list-item", count: 100)
- scroll_to(find(".channel-members-view__list-item:nth-child(100)"))
+ scroll_to(find(".chat-channel-members__list-item:nth-child(100)"))
- expect(page).to have_selector(".channel-members-view__list-item", count: 100, wait: 15)
+ expect(page).to have_selector(".chat-channel-members__list-item", count: 100)
end
context "with filter" do
@@ -62,9 +62,9 @@ RSpec.describe "Channel - Info - Members page", type: :system do
Jobs::Chat::UpdateChannelUserCount.new.execute(chat_channel_id: channel_1.id)
chat_page.visit_channel_members(channel_1)
- find(".channel-members-view__search-input").fill_in(with: "cat")
+ find(".chat-channel-members__filter").fill_in(with: "cat")
- expect(page).to have_selector(".channel-members-view__list-item", count: 1, text: "cat")
+ expect(page).to have_selector(".chat-channel-members__list-item", count: 1, text: "cat")
end
end
end
diff --git a/plugins/chat/spec/system/channel_settings_page_spec.rb b/plugins/chat/spec/system/channel_settings_page_spec.rb
index 5196a3e8856..1e6631d69b9 100644
--- a/plugins/chat/spec/system/channel_settings_page_spec.rb
+++ b/plugins/chat/spec/system/channel_settings_page_spec.rb
@@ -1,15 +1,42 @@
# frozen_string_literal: true
RSpec.describe "Channel - Info - Settings page", type: :system do
- let(:chat_page) { PageObjects::Pages::Chat.new }
fab!(:current_user) { Fabricate(:user) }
fab!(:channel_1) { Fabricate(:category_channel) }
+ let(:chat_page) { PageObjects::Pages::Chat.new }
+ let(:toasts) { PageObjects::Components::Toasts.new }
+ let(:channel_settings_page) { PageObjects::Pages::ChatChannelSettings.new }
+
before do
chat_system_bootstrap
sign_in(current_user)
end
+ context "when visiting from browse page" do
+ context "when clicking back button" do
+ it "redirects to browse page" do
+ chat_page.visit_browse
+ find(".chat-channel-card__setting").click
+ find(".chat-full-page-header__back-btn").click
+
+ expect(page).to have_current_path("/chat/browse/open")
+ end
+ end
+ end
+
+ context "when visiting from channel page" do
+ context "when clicking back button" do
+ it "redirects to channel page" do
+ chat_page.visit_channel(channel_1)
+ find(".chat-channel-title-wrapper").click
+ find(".chat-full-page-header__back-btn").click
+
+ expect(page).to have_current_path(chat.channel_path(channel_1.slug, channel_1.id))
+ end
+ end
+ end
+
context "as unauthorized user" do
before { SiteSetting.chat_allowed_groups = Fabricate(:group).id }
@@ -20,194 +47,244 @@ RSpec.describe "Channel - Info - Settings page", type: :system do
end
end
- context "as authorized user" do
- context "as not member" do
- it "redirects to about tab" do
- chat_page.visit_channel_settings(channel_1)
+ context "as not allowed to see the channel" do
+ fab!(:channel_1) { Fabricate(:private_category_channel) }
- expect(page).to have_current_path("/chat/c/#{channel_1.slug}/#{channel_1.id}/info/about")
- end
+ it "redirects to browse page" do
+ chat_page.visit_channel_settings(channel_1)
- it "doesn’t have settings tab" do
- chat_page.visit_channel_settings(channel_1)
+ expect(page).to have_current_path("/chat/browse/open")
+ end
+ end
- expect(page).to have_no_selector(".chat-tabs-list__item[aria-controls='settings-tab']")
- end
+ context "as not member of channel" do
+ it "shows settings page" do
+ chat_page.visit_channel_settings(channel_1)
- context "as an admin" do
- before { sign_in(Fabricate(:admin)) }
+ expect(page).to have_current_path("/chat/c/#{channel_1.slug}/#{channel_1.id}/info/settings")
+ end
+ end
- it "shows settings tab" do
- chat_page.visit_channel_settings(channel_1)
+ context "as regular user of channel" do
+ before { channel_1.add(current_user) }
- expect(page).to have_selector(".chat-tabs-list__item[aria-controls='settings-tab']")
- end
+ it "shows settings page" do
+ chat_page.visit_channel_settings(channel_1)
- it "can navigate to settings tab" do
- chat_page.visit_channel_settings(channel_1)
-
- expect(page).to have_current_path(
- "/chat/c/#{channel_1.slug}/#{channel_1.id}/info/settings",
- )
- end
- end
+ expect(page).to have_current_path("/chat/c/#{channel_1.slug}/#{channel_1.id}/info/settings")
end
- context "as a member" do
- before { channel_1.add(current_user) }
+ it "shows channel info" do
+ chat_page.visit_channel_settings(channel_1)
- context "when visiting the settings of a recently joined channel" do
- fab!(:channel_2) { Fabricate(:category_channel) }
+ expect(page.find(".category-name")).to have_content(channel_1.chatable.name)
+ expect(page.find(".chat-channel-settings__name")).to have_content(channel_1.title)
+ expect(page.find(".chat-channel-settings__slug")).to have_content(channel_1.slug)
+ end
- it "is correctly populated" do
- chat_page.visit_browse
- find(
- ".chat-channel-card[data-channel-id='#{channel_2.id}'] .toggle-channel-membership-button",
- ).click
+ it "can’t edit name or slug" do
+ chat_page.visit_channel_settings(channel_1)
- expect(
- page.find(".chat-channel-card[data-channel-id='#{channel_2.id}']"),
- ).to have_content(I18n.t("js.chat.joined").upcase)
+ expect(page).to have_no_selector(".edit-name-slug-btn")
+ end
- find(
- ".chat-channel-card[data-channel-id='#{channel_2.id}'] .chat-channel-card__setting",
- ).click
+ it "can’t edit description" do
+ chat_page.visit_channel_settings(channel_1)
- expect(page).to have_content(I18n.t("js.chat.notification_levels.mention"))
- end
- end
+ expect(page).to have_no_selector(".edit-description-btn")
+ end
- it "can mute channel" do
- chat_page.visit_channel_settings(channel_1)
- membership = channel_1.membership_for(current_user)
+ it "escapes channel title" do
+ channel_1.update!(name: "")
+ chat_page.visit_channel_settings(channel_1)
- expect {
- select_kit =
- PageObjects::Components::SelectKit.new(".-mute .channel-settings-view__selector")
- select_kit.expand
- select_kit.select_row_by_name("On")
+ expect(page.find(".chat-channel-settings__name")["innerHTML"].strip).to eq(
+ "<script>alert('hello')</script>",
+ )
+ expect(page.find(".chat-channel-title__name")["innerHTML"].strip).to eq(
+ "<script>alert('hello')</script>",
+ )
+ end
- expect(page).to have_content(I18n.t("js.chat.settings.saved"))
- }.to change { membership.reload.muted }.from(false).to(true)
- end
+ it "is not showing admin section" do
+ chat_page.visit_channel_settings(channel_1)
- it "can change desktop notification level" do
- chat_page.visit_channel_settings(channel_1)
- membership = channel_1.membership_for(current_user)
+ expect(page).to have_no_css("[data-section='admin']")
+ end
- expect {
- select_kit =
- PageObjects::Components::SelectKit.new(
- ".-desktop-notification-level .channel-settings-view__selector",
- )
- select_kit.expand
- select_kit.select_row_by_name("Never")
+ it "can mute channel" do
+ chat_page.visit_channel_settings(channel_1)
+ membership = channel_1.membership_for(current_user)
- expect(page).to have_content(I18n.t("js.chat.settings.saved"))
- }.to change { membership.reload.desktop_notification_level }.from("mention").to("never")
- end
+ expect {
+ PageObjects::Components::DToggleSwitch.new(".chat-channel-settings__mute-switch").toggle
- it "can change mobile notification level" do
- chat_page.visit_channel_settings(channel_1)
- membership = channel_1.membership_for(current_user)
+ expect(toasts).to have_success(I18n.t("js.saved"))
+ }.to change { membership.reload.muted }.from(false).to(true)
+ end
- expect {
- select_kit =
- PageObjects::Components::SelectKit.new(
- ".-mobile-notification-level .channel-settings-view__selector",
- )
- select_kit.expand
- select_kit.select_row_by_name("Never")
+ it "can change desktop notification level" do
+ chat_page.visit_channel_settings(channel_1)
+ membership = channel_1.membership_for(current_user)
- expect(page).to have_content(I18n.t("js.chat.settings.saved"))
- }.to change { membership.reload.mobile_notification_level }.from("mention").to("never")
- end
+ expect {
+ select_kit =
+ PageObjects::Components::SelectKit.new(
+ ".chat-channel-settings__desktop-notifications-selector",
+ )
+ select_kit.expand
+ select_kit.select_row_by_name("Never")
- it "doesn’t show admin section" do
- chat_page.visit_channel_settings(channel_1)
+ expect(toasts).to have_success(I18n.t("js.saved"))
+ }.to change { membership.reload.desktop_notification_level }.from("mention").to("never")
+ end
- expect(page).to have_no_content(I18n.t("js.chat.settings.admin_title"))
- end
+ it "can change mobile notification level" do
+ chat_page.visit_channel_settings(channel_1)
+ membership = channel_1.membership_for(current_user)
- context "as an admin" do
- before { sign_in(Fabricate(:admin)) }
+ expect {
+ select_kit =
+ PageObjects::Components::SelectKit.new(
+ ".chat-channel-settings__mobile-notifications-selector",
+ )
+ select_kit.expand
+ select_kit.select_row_by_name("Never")
- it "shows admin section" do
- chat_page.visit_channel_settings(channel_1)
+ expect(toasts).to have_success(I18n.t("js.saved"))
+ }.to change { membership.reload.mobile_notification_level }.from("mention").to("never")
+ end
+ end
- expect(page).to have_content(I18n.t("js.chat.settings.admin_title"))
- end
+ context "as staff" do
+ fab!(:current_user) { Fabricate(:admin) }
- it "can change auto join setting" do
- chat_page.visit_channel_settings(channel_1)
+ it "can edit name" do
+ chat_page.visit_channel_settings(channel_1)
- expect {
- select_kit =
- 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
+ edit_modal = channel_settings_page.open_edit_modal
- expect(page).to have_content(I18n.t("js.chat.settings.saved"))
- }.to change { channel_1.reload.auto_join_users }.from(false).to(true)
- end
+ expect(edit_modal).to have_name_input(channel_1.title)
- it "can change allow channel wide mentions" do
- chat_page.visit_channel_settings(channel_1)
+ name = "A new name"
- expect {
- select_kit =
- PageObjects::Components::SelectKit.new(
- ".-channel-wide-mentions .channel-settings-view__selector",
- )
- select_kit.expand
- select_kit.select_row_by_name("No")
+ edit_modal.fill_and_save_name(name)
- expect(page).to have_content(I18n.t("js.chat.settings.saved"))
- }.to change { channel_1.reload.allow_channel_wide_mentions }.from(true).to(false)
- end
+ expect(channel_settings_page).to have_name(name)
+ end
- it "can close channel" do
- chat_page.visit_channel_settings(channel_1)
+ it "can edit description" do
+ chat_page.visit_channel_settings(channel_1)
+ find(".edit-description-btn").click
- expect {
- click_button(I18n.t("js.chat.channel_settings.close_channel"))
- find("#chat-channel-toggle-btn").click
- expect(page).to have_content(I18n.t("js.chat.channel_status.closed_header"))
- }.to change { channel_1.reload.status }.from("open").to("closed")
- end
+ expect(page).to have_selector(
+ ".chat-modal-edit-channel-description__description-input",
+ text: channel_1.description,
+ )
- it "can enable threading" do
- chat_page.visit_channel_settings(channel_1)
+ description = "A new description"
+ find(".chat-modal-edit-channel-description__description-input").fill_in(with: description)
+ find(".create").click
- 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
+ expect(page).to have_content(description)
+ end
- it "can delete channel" do
- chat_page.visit_channel_settings(channel_1)
+ it "can edit slug" do
+ chat_page.visit_channel_settings(channel_1)
+ edit_modal = channel_settings_page.open_edit_modal
- click_button(I18n.t("js.chat.channel_settings.delete_channel"))
- fill_in("channel-delete-confirm-name", with: channel_1.title)
- find_button("chat-confirm-delete-channel", disabled: false).click
- expect(page).to have_content(I18n.t("js.chat.channel_delete.process_started"))
- end
+ slug = "gonzo-slug"
- context "when confirmation name is wrong" do
- it "doesn’t delete submission" do
- chat_page.visit_channel_settings(channel_1)
- find(".delete-btn").click
- fill_in("channel-delete-confirm-name", with: channel_1.title + "wrong")
+ expect(edit_modal).to have_slug_input(channel_1.slug)
- expect(page).to have_button("chat-confirm-delete-channel", disabled: true)
- end
- end
- end
+ edit_modal.fill_and_save_slug(slug)
+
+ expect(channel_settings_page).to have_slug(slug)
+ end
+
+ it "can clear the slug to use the autogenerated version based on the name" do
+ channel_1.update!(name: "test channel")
+ chat_page.visit_channel_settings(channel_1)
+ edit_modal = channel_settings_page.open_edit_modal
+
+ expect(edit_modal).to have_slug_input(channel_1.slug)
+
+ edit_modal.fill_in_slug_input("")
+ edit_modal.wait_for_auto_generated_slug
+ edit_modal.save_changes
+
+ expect(channel_settings_page).to have_slug("test-channel")
+ end
+
+ it "shows settings page" do
+ chat_page.visit_channel_settings(channel_1)
+
+ expect(page).to have_current_path("/chat/c/#{channel_1.slug}/#{channel_1.id}/info/settings")
+ end
+
+ it "can change auto join setting" do
+ chat_page.visit_channel_settings(channel_1)
+
+ expect {
+ PageObjects::Components::DToggleSwitch.new(
+ ".chat-channel-settings__auto-join-switch",
+ ).toggle
+ find("#dialog-holder .btn-primary").click
+
+ expect(toasts).to have_success(I18n.t("js.saved"))
+ }.to change { channel_1.reload.auto_join_users }.from(false).to(true)
+ end
+
+ it "can change allow channel wide mentions" do
+ chat_page.visit_channel_settings(channel_1)
+
+ expect {
+ PageObjects::Components::DToggleSwitch.new(
+ ".chat-channel-settings__channel-wide-mentions",
+ ).toggle
+
+ expect(toasts).to have_success(I18n.t("js.saved"))
+ }.to change { channel_1.reload.allow_channel_wide_mentions }.from(true).to(false)
+ end
+
+ it "can close channel" do
+ chat_page.visit_channel_settings(channel_1)
+
+ expect {
+ click_button(I18n.t("js.chat.channel_settings.close_channel"))
+ find("#chat-channel-toggle-btn").click
+
+ expect(page).to have_content(I18n.t("js.chat.channel_status.closed_header"))
+ }.to change { channel_1.reload.status }.from("open").to("closed")
+ end
+
+ it "can enable threading" do
+ chat_page.visit_channel_settings(channel_1)
+
+ expect {
+ PageObjects::Components::DToggleSwitch.new(
+ ".chat-channel-settings__threading-switch",
+ ).toggle
+
+ expect(toasts).to have_success(I18n.t("js.saved"))
+ }.to change { channel_1.reload.threading_enabled }.from(false).to(true)
+ end
+
+ it "can delete channel" do
+ chat_page.visit_channel_settings(channel_1)
+
+ click_button(I18n.t("js.chat.channel_settings.delete_channel"))
+ fill_in("channel-delete-confirm-name", with: channel_1.title)
+ find_button("chat-confirm-delete-channel", disabled: false).click
+ expect(page).to have_content(I18n.t("js.chat.channel_delete.process_started"))
+ end
+
+ it "doesn’t delete when confirmation is wrong" do
+ chat_page.visit_channel_settings(channel_1)
+ find(".delete-btn").click
+ fill_in("channel-delete-confirm-name", with: channel_1.title + "wrong")
+
+ expect(page).to have_button("chat-confirm-delete-channel", disabled: true)
end
end
end
diff --git a/plugins/chat/spec/system/drawer_spec.rb b/plugins/chat/spec/system/drawer_spec.rb
index 4def6cbd4e3..6e6c072094a 100644
--- a/plugins/chat/spec/system/drawer_spec.rb
+++ b/plugins/chat/spec/system/drawer_spec.rb
@@ -24,7 +24,7 @@ RSpec.describe "Drawer", type: :system do
drawer_page.open_channel(channel)
page.find(".chat-channel-title").click
- expect(page).to have_current_path("/chat/c/#{channel.slug}/#{channel.id}/info/about")
+ expect(page).to have_current_path("/chat/c/#{channel.slug}/#{channel.id}/info/settings")
end
end
end
diff --git a/plugins/chat/spec/system/page_objects/chat/chat.rb b/plugins/chat/spec/system/page_objects/chat/chat.rb
index d2fa99777c8..2b9a3117fc5 100644
--- a/plugins/chat/spec/system/page_objects/chat/chat.rb
+++ b/plugins/chat/spec/system/page_objects/chat/chat.rb
@@ -63,10 +63,6 @@ module PageObjects
visit(channel.url + "/info/settings")
end
- def visit_channel_about(channel)
- visit(channel.url + "/info/about")
- end
-
def visit_channel_members(channel)
visit(channel.url + "/info/members")
end
diff --git a/plugins/chat/spec/system/page_objects/chat/chat_channel_about.rb b/plugins/chat/spec/system/page_objects/chat/chat_channel_settings.rb
similarity index 68%
rename from plugins/chat/spec/system/page_objects/chat/chat_channel_about.rb
rename to plugins/chat/spec/system/page_objects/chat/chat_channel_settings.rb
index a28836bb59f..34d9ee1b8b1 100644
--- a/plugins/chat/spec/system/page_objects/chat/chat_channel_about.rb
+++ b/plugins/chat/spec/system/page_objects/chat/chat_channel_settings.rb
@@ -2,7 +2,7 @@
module PageObjects
module Pages
- class ChatChannelAbout < PageObjects::Pages::Base
+ class ChatChannelSettings < PageObjects::Pages::Base
EDIT_MODAL_SELECTOR = ".chat-modal-edit-channel-name"
def open_edit_modal
@@ -12,11 +12,11 @@ module PageObjects
end
def has_slug?(slug)
- page.has_css?(".channel-info-about-view__slug", text: slug)
+ page.has_css?(".chat-channel-settings__slug", text: slug)
end
def has_name?(name)
- page.has_css?(".channel-info-about-view__name", text: name)
+ page.has_css?(".chat-channel-settings__name", text: name)
end
end
end
diff --git a/plugins/chat/spec/system/page_objects/modals/chat_edit_modal.rb b/plugins/chat/spec/system/page_objects/modals/chat_edit_modal.rb
index d678db64485..0930ccb0970 100644
--- a/plugins/chat/spec/system/page_objects/modals/chat_edit_modal.rb
+++ b/plugins/chat/spec/system/page_objects/modals/chat_edit_modal.rb
@@ -5,7 +5,7 @@ module PageObjects
class ChatChannelEdit < PageObjects::Modals::Base
include SystemHelpers
- EDIT_MODAL_SELECTOR = PageObjects::Pages::ChatChannelAbout::EDIT_MODAL_SELECTOR
+ EDIT_MODAL_SELECTOR = PageObjects::Pages::ChatChannelSettings::EDIT_MODAL_SELECTOR
SLUG_INPUT_SELECTOR = ".chat-channel-edit-name-slug-modal__slug-input"
NAME_INPUT_SELECTOR = ".chat-channel-edit-name-slug-modal__name-input"
diff --git a/plugins/chat/test/javascripts/components/chat-channel-settings-saved-indicator-test.js b/plugins/chat/test/javascripts/components/chat-channel-settings-saved-indicator-test.js
deleted file mode 100644
index 6f03050cb05..00000000000
--- a/plugins/chat/test/javascripts/components/chat-channel-settings-saved-indicator-test.js
+++ /dev/null
@@ -1,31 +0,0 @@
-import { module, test } from "qunit";
-import { setupRenderingTest } from "discourse/tests/helpers/component-test";
-import { render, settled } from "@ember/test-helpers";
-import { hbs } from "ember-cli-htmlbars";
-
-module(
- "Discourse Chat | Component | chat-channel-settings-saved-indicator",
- function (hooks) {
- setupRenderingTest(hooks);
-
- test("when property changes", async function (assert) {
- await render(
- hbs`
`
- );
-
- assert
- .dom(".chat-channel-settings-saved-indicator.is-active")
- .doesNotExist();
-
- this.set("property", 1);
-
- assert.dom(".chat-channel-settings-saved-indicator.is-active").exists();
-
- await settled();
-
- assert
- .dom(".chat-channel-settings-saved-indicator.is-active")
- .doesNotExist();
- });
- }
-);
diff --git a/plugins/chat/test/javascripts/components/chat-channel-settings-view-test.js b/plugins/chat/test/javascripts/components/chat-channel-settings-view-test.js
deleted file mode 100644
index 3bc294b528f..00000000000
--- a/plugins/chat/test/javascripts/components/chat-channel-settings-view-test.js
+++ /dev/null
@@ -1,25 +0,0 @@
-import ChatChannel from "discourse/plugins/chat/discourse/models/chat-channel";
-import { setupRenderingTest } from "discourse/tests/helpers/component-test";
-import hbs from "htmlbars-inline-precompile";
-import I18n from "I18n";
-import { module, test } from "qunit";
-import { render } from "@ember/test-helpers";
-
-module(
- "Discourse Chat | Component | chat-channel-settings-view",
- function (hooks) {
- setupRenderingTest(hooks);
-
- test("display retention info", async function (assert) {
- this.set("channel", ChatChannel.create({ chatable_type: "Category" }));
-
- await render(hbs`
`);
-
- assert.dom(".chat-retention-info").hasText(
- I18n.t("chat.retention_reminders.public", {
- count: this.siteSettings.chat_channel_retention_days,
- })
- );
- });
- }
-);
diff --git a/spec/system/page_objects/components/d_toggle_switch.rb b/spec/system/page_objects/components/d_toggle_switch.rb
new file mode 100644
index 00000000000..5569a83a678
--- /dev/null
+++ b/spec/system/page_objects/components/d_toggle_switch.rb
@@ -0,0 +1,22 @@
+# frozen_string_literal: true
+
+module PageObjects
+ module Components
+ class DToggleSwitch < PageObjects::Components::Base
+ attr_reader :context
+
+ def initialize(context)
+ @context = context
+ end
+
+ def component
+ find(@context, visible: :all).native
+ end
+
+ def toggle
+ actionbuilder = page.driver.browser.action # workaround zero height button
+ actionbuilder.click(component).perform
+ end
+ end
+ end
+end