;
+ }, [mode, customIcon]);
+
+ const dismissButton = useMemo(() => {
+ return (
+
+
+
+ );
+ }, [onDismiss]);
+
+ return (
+
+ {!hideIcon && (
+
+ {bannerIcon}
+
+ )}
+
+ {title &&
+
+ {title}
+
+ }
+ {message && (
+
+ {message}
+
+ )}
+ {children}
+ {(actionButtonLeft || actionButtonRight) && (
+
+ {actionButtonLeft}
+ {actionButtonRight}
+
+ )}
+ {footerMessage && (
+
+ {footerMessage}
+
+ )}
+
+ {onDismiss && closeBtnTooltip && (
+
+ {dismissButton}
+
+ )}
+ {onDismiss && !closeBtnTooltip && (
+ dismissButton
+ )}
+
+ );
+};
+
+export default AlertBanner;
diff --git a/webapp/channels/src/components/channel_notifications_modal/__snapshots__/channel_notifications_modal.test.tsx.snap b/webapp/channels/src/components/channel_notifications_modal/__snapshots__/channel_notifications_modal.test.tsx.snap
index d00414fa8d..0b27528c39 100644
--- a/webapp/channels/src/components/channel_notifications_modal/__snapshots__/channel_notifications_modal.test.tsx.snap
+++ b/webapp/channels/src/components/channel_notifications_modal/__snapshots__/channel_notifications_modal.test.tsx.snap
@@ -52,20 +52,11 @@ Object {
class="mm-modal-header__ctr"
>
@@ -76,16 +67,16 @@ Object {
class="mm-modal-generic-section"
>
Mute or ignore
- Turns off notifications for this channel. You’ll still see badges if you’re mentioned.
+ Turns off notifications for this channel. You'll still see badges if you're mentioned.
Ignore mentions for @channel, @here and @all
-
-
-
- Desktop Notifications
-
-
+ Desktop Notifications
+
Available on Chrome, Edge, Firefox, and the Mattermost Desktop App.
-
-
- Mobile Notifications
-
+ Mobile Notifications
@@ -271,15 +252,15 @@ Object {
Reset to default
-
+
Notification alerts are pushed to your mobile device when there is activity in Mattermost.
Use the same notification settings as desktop
-
@@ -370,12 +350,12 @@ Object {
>
Cancel
Save
@@ -496,20 +476,11 @@ Object {
class="mm-modal-header__ctr"
>
@@ -520,16 +491,16 @@ Object {
class="mm-modal-generic-section"
>
Mute or ignore
- Turns off notifications for this channel. You’ll still see badges if you’re mentioned.
+ Turns off notifications for this channel. You'll still see badges if you're mentioned.
Ignore mentions for @channel, @here and @all
-
-
-
- Desktop Notifications
-
+ Desktop Notifications
@@ -629,15 +594,15 @@ Object {
Reset to default
-
+
Available on Chrome, Edge, Firefox, and the Mattermost Desktop App.
-
-
- Mobile Notifications
-
+ Mobile Notifications
@@ -732,15 +693,15 @@ Object {
Reset to default
-
+
Notification alerts are pushed to your mobile device when there is activity in Mattermost.
Use the same notification settings as desktop
-
@@ -831,12 +791,12 @@ Object {
>
Cancel
Save
@@ -957,20 +917,11 @@ Object {
class="mm-modal-header__ctr"
>
@@ -981,16 +932,16 @@ Object {
class="mm-modal-generic-section"
>
Mute or ignore
- Turns off notifications for this channel. You’ll still see badges if you’re mentioned.
+ Turns off notifications for this channel. You'll still see badges if you're mentioned.
Ignore mentions for @channel, @here and @all
-
-
-
- Desktop Notifications
-
-
+ Desktop Notifications
+
Available on Chrome, Edge, Firefox, and the Mattermost Desktop App.
-
-
- Mobile Notifications
-
+ Mobile Notifications
@@ -1176,15 +1117,15 @@ Object {
Reset to default
-
+
Notification alerts are pushed to your mobile device when there is activity in Mattermost.
Use the same notification settings as desktop
-
@@ -1275,12 +1215,12 @@ Object {
>
Cancel
Save
@@ -1401,20 +1341,11 @@ Object {
class="mm-modal-header__ctr"
>
@@ -1425,16 +1356,16 @@ Object {
class="mm-modal-generic-section"
>
Mute or ignore
- Turns off notifications for this channel. You’ll still see badges if you’re mentioned.
+ Turns off notifications for this channel. You'll still see badges if you're mentioned.
Ignore mentions for @channel, @here and @all
-
Cancel
Save
@@ -1666,20 +1596,11 @@ Object {
class="mm-modal-header__ctr"
>
@@ -1690,16 +1611,16 @@ Object {
class="mm-modal-generic-section"
>
Mute or ignore
- Turns off notifications for this channel. You’ll still see badges if you’re mentioned.
+ Turns off notifications for this channel. You'll still see badges if you're mentioned.
Ignore mentions for @channel, @here and @all
-
-
-
- Desktop Notifications
-
-
+ Desktop Notifications
+
Available on Chrome, Edge, Firefox, and the Mattermost Desktop App.
-
-
- Mobile Notifications
-
+ Mobile Notifications
@@ -1885,15 +1796,15 @@ Object {
Reset to default
-
+
Notification alerts are pushed to your mobile device when there is activity in Mattermost.
Use the same notification settings as desktop
-
@@ -1928,12 +1838,12 @@ Object {
>
Cancel
Save
@@ -2054,20 +1964,11 @@ Object {
class="mm-modal-header__ctr"
>
@@ -2078,16 +1979,16 @@ Object {
class="mm-modal-generic-section"
>
Mute or ignore
- Turns off notifications for this channel. You’ll still see badges if you’re mentioned.
+ Turns off notifications for this channel. You'll still see badges if you're mentioned.
Ignore mentions for @channel, @here and @all
-
-
-
- Desktop Notifications
-
-
+ Desktop Notifications
+
Available on Chrome, Edge, Firefox, and the Mattermost Desktop App.
-
-
- Mobile Notifications
-
+ Mobile Notifications
@@ -2273,15 +2164,15 @@ Object {
Reset to default
-
+
Notification alerts are pushed to your mobile device when there is activity in Mattermost.
Use the same notification settings as desktop
-
@@ -2373,21 +2263,21 @@ Object {
class="mm-modal-generic-section"
>
Follow all threads in this channel
When enabled, all new replies in this channel will be automatically followed and will appear in your Threads view.
Automatically follow threads in this channel
-
@@ -2422,12 +2311,12 @@ Object {
>
Cancel
Save
diff --git a/webapp/channels/src/components/channel_notifications_modal/channel_notifications_modal.scss b/webapp/channels/src/components/channel_notifications_modal/channel_notifications_modal.scss
index 84d87c5990..ee01847fc2 100644
--- a/webapp/channels/src/components/channel_notifications_modal/channel_notifications_modal.scss
+++ b/webapp/channels/src/components/channel_notifications_modal/channel_notifications_modal.scss
@@ -31,7 +31,7 @@
max-width: 1024px;
min-height: 150px;
flex-direction: column;
- padding: 32px;
+ padding: 28px 32px;
gap: 24px;
overflow-x: hidden;
overflow-y: auto;
@@ -72,48 +72,6 @@
color: var(--error-text);
}
- &__save-btn {
- padding: 12px 20px 12px 20px;
- border: none;
- border-radius: 4px;
- background: var(--button-bg);
- color: var(--button-color);
- font-size: 14px;
- font-weight: 600;
- line-height: 14px;
- text-transform: capitalize;
-
- &:hover,
- &:active {
- background: rgba(var(--button-bg-rgb), 0.12);
- background: linear-gradient(0deg, rgba(0, 0, 0, 0.08), rgba(0, 0, 0, 0.08)), var(--button-bg);
- }
-
- &:focus {
- box-sizing: border-box;
- padding: 10px 18px;
- border: 2px solid var(--sidebar-text-active-border);
- box-shadow: none;
- }
- }
-
- &__cancel-btn {
- padding: 12px 20px 12px 20px;
- border: none;
- border-radius: 4px;
- background: rgba(var(--button-bg-rgb), 0.08);
- color: var(--button-bg);
- font-size: 14px;
- font-weight: 600;
- line-height: 14px;
- text-transform: capitalize;
-
- &:hover,
- &:active {
- background: rgba(var(--button-bg-rgb), 0.12);
- }
- }
-
&__divider {
border-bottom: 1px solid rgba(var(--center-channel-color-rgb), 0.08);
}
diff --git a/webapp/channels/src/components/channel_notifications_modal/channel_notifications_modal.tsx b/webapp/channels/src/components/channel_notifications_modal/channel_notifications_modal.tsx
index 38f52bda61..1c12e76c5c 100644
--- a/webapp/channels/src/components/channel_notifications_modal/channel_notifications_modal.tsx
+++ b/webapp/channels/src/components/channel_notifications_modal/channel_notifications_modal.tsx
@@ -43,10 +43,8 @@ type Props = PropsFromRedux & {
};
function getUseSameDesktopSetting(currentUserNotifyProps: UserNotifyProps, channelMemberNotifyProps?: ChannelMemberNotifyProps) {
- const isSameAsDesktop = channelMemberNotifyProps ? channelMemberNotifyProps?.desktop === channelMemberNotifyProps?.push :
- currentUserNotifyProps.push === currentUserNotifyProps.desktop;
- const isSameAsDesktopThreads = channelMemberNotifyProps ? channelMemberNotifyProps?.desktop_threads === channelMemberNotifyProps?.push_threads :
- currentUserNotifyProps.push_threads === currentUserNotifyProps.desktop_threads;
+ const isSameAsDesktop = channelMemberNotifyProps ? channelMemberNotifyProps?.desktop === channelMemberNotifyProps?.push : currentUserNotifyProps.push === currentUserNotifyProps.desktop;
+ const isSameAsDesktopThreads = channelMemberNotifyProps ? channelMemberNotifyProps?.desktop_threads === channelMemberNotifyProps?.push_threads : currentUserNotifyProps.push_threads === currentUserNotifyProps.desktop_threads;
return isSameAsDesktop && isSameAsDesktopThreads;
}
@@ -106,16 +104,34 @@ export default function ChannelNotificationsModal(props: Props) {
setSettings((prevSettings) => ({...prevSettings, push: prevSettings.desktop, push_threads: prevSettings.desktop_threads}));
}, []);
- const MuteIgnoreSectionContent = (
+ const MuteOrIgnoreSectionContent = (
<>
+ }
+ description={formatMessage({
+ id: 'channel_notifications.muteChannelDesc',
+ defaultMessage: 'Turns off notifications for this channel. You\'ll still see badges if you\'re mentioned.',
+ })}
inputFieldValue={settings.mark_unread === 'mention'}
inputFieldData={utils.MuteChannelInputFieldData}
handleChange={(e) => handleChange({mark_unread: e ? 'mention' : 'all'})}
/>
+ }
+ description={formatMessage({
+ id: 'channel_notifications.ignoreMentionsDesc',
+ defaultMessage: 'When enabled, @channel, @here and @all will not trigger mentions or mention notifications in this channel',
+ })}
inputFieldValue={settings.ignore_channel_mentions === 'on'}
inputFieldData={utils.IgnoreMentionsInputFieldData}
handleChange={(e) => handleChange({ignore_channel_mentions: e ? 'on' : 'off'})}
@@ -126,16 +142,28 @@ export default function ChannelNotificationsModal(props: Props) {
const DesktopNotificationsSectionContent = (
<>
handleChange({desktop: e.target.value})}
/>
{props.collapsedReplyThreads && settings.desktop === 'mention' &&
+ }
handleChange={(e) => handleChange({desktop_threads: e ? 'all' : 'mention'})}
/>}
>
@@ -144,6 +172,12 @@ export default function ChannelNotificationsModal(props: Props) {
const MobileNotificationsSectionContent = (
<>
+ }
inputFieldValue={mobileSettingsSameAsDesktop}
inputFieldData={utils.sameMobileSettingsDesktopInputFieldData}
handleChange={() => handleMobileSettingsChange()}
@@ -151,14 +185,26 @@ export default function ChannelNotificationsModal(props: Props) {
{!mobileSettingsSameAsDesktop && (
<>
handleChange({push: e.target.value})}
/>
{props.collapsedReplyThreads && settings.push === 'mention' &&
+ }
inputFieldValue={settings.push_threads === 'all'}
inputFieldData={utils.MobileReplyThreadsInputFieldData}
handleChange={(e) => handleChange({push_threads: e ? 'all' : 'mention'})}
@@ -169,13 +215,17 @@ export default function ChannelNotificationsModal(props: Props) {
);
const AutoFollowThreadsSectionContent = (
- <>
- handleChange({channel_auto_follow_threads: e ? 'on' : 'off'})}
- />
- >
+
+ }
+ inputFieldValue={settings.channel_auto_follow_threads === 'on'}
+ inputFieldData={utils.AutoFollowThreadsInputFieldData}
+ handleChange={(e) => handleChange({channel_auto_follow_threads: e ? 'on' : 'off'})}
+ />
);
function handleSave() {
@@ -229,25 +279,38 @@ export default function ChannelNotificationsModal(props: Props) {
);
}, [props.currentUser, settings]);
- const settingsAndAlertBanner = settings.mark_unread === 'all' ? (
+ const desktopAndMobileNotificationSectionContent = settings.mark_unread === 'all' ? (
<>
>
) : (
- {settingsAndAlertBanner}
+ {desktopAndMobileNotificationSectionContent}
{props.collapsedReplyThreads &&
<>
>
@@ -314,8 +386,8 @@ export default function ChannelNotificationsModal(props: Props) {
}
& Pick
-const translations = defineMessages({
- MuteAndIgnoreSectionTitle: {
- id: 'channel_notifications.muteAndIgnore',
- defaultMessage: 'Mute or ignore',
- },
- NotifyMeTitle: {
- id: 'channel_notifications.NotifyMeTitle',
- defaultMessage: 'Notify me about…',
- },
- ThreadsReplyTitle: {
- id: 'channel_notifications.ThreadsReplyTitle',
- defaultMessage: 'Thread reply notifications',
- },
-
- DesktopNotificationsSectionTitle: {
- id: 'channel_notifications.desktopNotificationsTitle',
- defaultMessage: 'Desktop Notifications',
- },
-
- DesktopNotificationsSectionDesc: {
- id: 'channel_notifications.desktopNotificationsDesc',
- defaultMessage: 'Available on Chrome, Edge, Firefox, and the Mattermost Desktop App.',
- },
-
- MobileNotificationsSectionTitle: {
- id: 'channel_notifications.mobileNotificationsTitle',
- defaultMessage: 'Mobile Notifications',
- },
-
- MobileNotificationsSectionDesc: {
- id: 'channel_notifications.mobileNotificationsDesc',
- defaultMessage: 'Notification alerts are pushed to your mobile device when there is activity in Mattermost.',
- },
-
- MuteChannelDesc: {
- id: 'channel_notifications.muteChannelDesc',
- defaultMessage: 'Turns off notifications for this channel. You’ll still see badges if you’re mentioned.',
- },
-
- IgnoreMentionsDesc: {
- id: 'channel_notifications.ignoreMentionsDesc',
- defaultMessage: 'When enabled, @channel, @here and @all will not trigger mentions or mention notifications in this channel',
- },
-
- MuteChannelInputFieldTitle: {
- id: 'channel_notifications.muteChannelTitle',
- defaultMessage: 'Mute channel',
- },
-
- DesktopReplyThreadsInputFieldTitle: {
- id: 'channel_notifications.checkbox.threadsReplyTitle',
- defaultMessage: 'Notify me about replies to threads I\'m following',
- },
-
- MobileReplyThreadsInputFieldTitle: {
- id: 'channel_notifications.checkbox.threadsReplyTitle',
- defaultMessage: 'Notify me about replies to threads I\'m following',
- },
-
- sameMobileSettingsDesktopInputFieldTitle: {
- id: 'channel_notifications.checkbox.sameMobileSettingsDesktop',
- defaultMessage: 'Use the same notification settings as desktop',
- },
-
- IgnoreMentionsInputFieldTitle: {
- id: 'channel_notifications.ignoreMentionsTitle',
- defaultMessage: 'Ignore mentions for @channel, @here and @all',
- },
-
- AutoFollowThreadsTitle: {
- id: 'channel_notifications.autoFollowThreadsTitle',
- defaultMessage: 'Follow all threads in this channel',
- },
-
- AutoFollowThreadsDesc: {
- id: 'channel_notifications.autoFollowThreadsDesc',
- defaultMessage: 'When enabled, all new replies in this channel will be automatically followed and will appear in your Threads view.',
- },
-
- AutoFollowThreadsInputFieldTitle: {
- id: 'channel_notifications.checkbox.autoFollowThreadsTitle',
- defaultMessage: 'Automatically follow threads in this channel',
- },
-});
-
-const desktopNotificationInputFieldOptions = defineMessages({
- allNewMessages: {
- id: 'channel_notifications.desktopNotificationAllLabel',
- defaultMessage: 'All new messages',
- },
- mentions: {
- id: 'channel_notifications.desktopNotificationMentionLabel',
- defaultMessage: 'Mentions, direct messages, and keywords only',
- },
- nothing: {
- id: 'channel_notifications.desktopNotificationNothingLabel',
- defaultMessage: 'Nothing',
- },
-});
-
-const mobileNotificationInputFieldOptions = defineMessages({
- allNewMessages: {
- id: 'channel_notifications.MobileNotificationAllLabel',
- defaultMessage: 'All new messages',
- },
- mentions: {
- id: 'channel_notifications.MobileNotificationMentionLabel',
- defaultMessage: 'Mentions, direct messages, and keywords only',
- },
- nothing: {
- id: 'channel_notifications.MobileNotificationNothingLabel',
- defaultMessage: 'Nothing',
- },
-});
-
const MuteChannelInputFieldData: FieldsetCheckbox = {
- title: translations.MuteChannelInputFieldTitle,
name: 'mute channel',
dataTestId: 'muteChannel',
};
const DesktopReplyThreadsInputFieldData: FieldsetCheckbox = {
- title: translations.DesktopReplyThreadsInputFieldTitle,
name: 'desktop reply threads',
dataTestId: 'desktopReplyThreads',
};
const MobileReplyThreadsInputFieldData: FieldsetCheckbox = {
- title: translations.MobileReplyThreadsInputFieldTitle,
name: 'mobile reply threads',
dataTestId: 'mobileReplyThreads',
};
-const sameMobileSettingsDesktopInputFieldData: FieldsetCheckbox = {
- title: translations.sameMobileSettingsDesktopInputFieldTitle,
+export const sameMobileSettingsDesktopInputFieldData: FieldsetCheckbox = {
name: 'same mobile settings as Desktop',
dataTestId: 'sameMobileSettingsDesktop',
};
-const IgnoreMentionsInputFieldData: FieldsetCheckbox = {
- title: translations.IgnoreMentionsInputFieldTitle,
+export const IgnoreMentionsInputFieldData: FieldsetCheckbox = {
name: 'ignore mentions',
dataTestId: 'ignoreMentions',
};
-const AutoFollowThreadsInputFieldData: FieldsetCheckbox = {
- title: translations.AutoFollowThreadsInputFieldTitle,
+export const AutoFollowThreadsInputFieldData: FieldsetCheckbox = {
name: 'auto follow threads',
dataTestId: 'autoFollowThreads',
};
-const desktopNotificationInputFieldData = (defaultOption: string): FieldsetRadio => {
+export const desktopNotificationInputFieldData = (defaultOption: string): FieldsetRadio => {
return {
options: [
{
dataTestId: `desktopNotification-${NotificationLevels.ALL}`,
- title: desktopNotificationInputFieldOptions.allNewMessages,
+ title: (
+
+ ),
name: `desktopNotification-${NotificationLevels.ALL}`,
key: `desktopNotification-${NotificationLevels.ALL}`,
value: NotificationLevels.ALL,
@@ -182,7 +66,12 @@ const desktopNotificationInputFieldData = (defaultOption: string): FieldsetRadio
},
{
dataTestId: `desktopNotification-${NotificationLevels.MENTION}`,
- title: desktopNotificationInputFieldOptions.mentions,
+ title: (
+
+ ),
name: `desktopNotification-${NotificationLevels.MENTION}`,
key: `desktopNotification-${NotificationLevels.MENTION}`,
value: NotificationLevels.MENTION,
@@ -194,7 +83,12 @@ const desktopNotificationInputFieldData = (defaultOption: string): FieldsetRadio
},
{
dataTestId: `desktopNotification-${NotificationLevels.NONE}`,
- title: desktopNotificationInputFieldOptions.nothing,
+ title: (
+
+ ),
name: `desktopNotification-${NotificationLevels.NONE}`,
key: `desktopNotification-${NotificationLevels.NONE}`,
value: NotificationLevels.NONE,
@@ -208,12 +102,17 @@ const desktopNotificationInputFieldData = (defaultOption: string): FieldsetRadio
};
};
-const mobileNotificationInputFieldData = (defaultOption: string): FieldsetRadio => {
+export const mobileNotificationInputFieldData = (defaultOption: string): FieldsetRadio => {
return {
options: [
{
dataTestId: `MobileNotification-${NotificationLevels.ALL}`,
- title: mobileNotificationInputFieldOptions.allNewMessages,
+ title: (
+
+ ),
name: `MobileNotification-${NotificationLevels.ALL}`,
key: `MobileNotification-${NotificationLevels.ALL}`,
value: NotificationLevels.ALL,
@@ -225,7 +124,12 @@ const mobileNotificationInputFieldData = (defaultOption: string): FieldsetRadio
},
{
dataTestId: `MobileNotification-${NotificationLevels.MENTION}`,
- title: mobileNotificationInputFieldOptions.mentions,
+ title: (
+
+ ),
name: `MobileNotification-${NotificationLevels.MENTION}`,
key: `MobileNotification-${NotificationLevels.MENTION}`,
value: NotificationLevels.MENTION,
@@ -237,7 +141,12 @@ const mobileNotificationInputFieldData = (defaultOption: string): FieldsetRadio
},
{
dataTestId: `MobileNotification-${NotificationLevels.NONE}`,
- title: mobileNotificationInputFieldOptions.nothing,
+ title: (
+
+ ),
name: `MobileNotification-${NotificationLevels.NONE}`,
key: `MobileNotification-${NotificationLevels.NONE}`,
value: NotificationLevels.NONE,
@@ -253,22 +162,11 @@ const mobileNotificationInputFieldData = (defaultOption: string): FieldsetRadio
const utils = {
desktopNotificationInputFieldData,
- DesktopNotificationsSectionDesc: translations.DesktopNotificationsSectionDesc,
- DesktopNotificationsSectionTitle: translations.DesktopNotificationsSectionTitle,
- IgnoreMentionsDesc: translations.IgnoreMentionsDesc,
IgnoreMentionsInputFieldData,
mobileNotificationInputFieldData,
- MobileNotificationsSectionDesc: translations.MobileNotificationsSectionDesc,
- MobileNotificationsSectionTitle: translations.MobileNotificationsSectionTitle,
- MuteAndIgnoreSectionTitle: translations.MuteAndIgnoreSectionTitle,
- MuteChannelDesc: translations.MuteChannelDesc,
MuteChannelInputFieldData,
- NotifyMeTitle: translations.NotifyMeTitle,
DesktopReplyThreadsInputFieldData,
- ThreadsReplyTitle: translations.ThreadsReplyTitle,
MobileReplyThreadsInputFieldData,
- AutoFollowThreadsTitle: translations.AutoFollowThreadsTitle,
- AutoFollowThreadsDesc: translations.AutoFollowThreadsDesc,
AutoFollowThreadsInputFieldData,
sameMobileSettingsDesktopInputFieldData,
};
diff --git a/webapp/channels/src/components/file_limit_sticky_banner/index.tsx b/webapp/channels/src/components/file_limit_sticky_banner/index.tsx
index 048dd762fd..599b561e25 100644
--- a/webapp/channels/src/components/file_limit_sticky_banner/index.tsx
+++ b/webapp/channels/src/components/file_limit_sticky_banner/index.tsx
@@ -16,7 +16,6 @@ import useGetLimits from 'components/common/hooks/useGetLimits';
import useGetUsage from 'components/common/hooks/useGetUsage';
import useOpenPricingModal from 'components/common/hooks/useOpenPricingModal';
import NotifyAdminCTA from 'components/notify_admin_cta/notify_admin_cta';
-import Tooltip from 'components/tooltip';
import {CloudProducts, LicenseSkus, MattermostFeatures, Preferences} from 'utils/constants';
import {asGBString} from 'utils/limits';
@@ -147,19 +146,13 @@ function FileLimitStickyBanner() {
/>
);
- const tooltip = (
-
- {formatMessage({id: 'create_post.file_limit_sticky_banner.snooze_tooltip', defaultMessage: 'Snooze for {snoozeDays} days'}, {snoozeDays: snoozeCoolOffDays})}
-
- );
-
return (
diff --git a/webapp/channels/src/components/team_settings/team_access_tab/allowed_domains_select.tsx b/webapp/channels/src/components/team_settings/team_access_tab/allowed_domains_select.tsx
index 7468cef11d..260f385d3c 100644
--- a/webapp/channels/src/components/team_settings/team_access_tab/allowed_domains_select.tsx
+++ b/webapp/channels/src/components/team_settings/team_access_tab/allowed_domains_select.tsx
@@ -2,27 +2,12 @@
// See LICENSE.txt for license information.
import React, {useCallback, useState} from 'react';
-import {defineMessages, useIntl} from 'react-intl';
+import {FormattedMessage, useIntl} from 'react-intl';
import SelectTextInput, {type SelectTextInputOption} from 'components/common/select_text_input/select_text_input';
import CheckboxSettingItem from 'components/widgets/modals/components/checkbox_setting_item';
import {type SaveChangesPanelState} from 'components/widgets/modals/components/save_changes_panel';
-const translations = defineMessages({
- AllowedDomainsTitle: {
- id: 'general_tab.AllowedDomainsTitle',
- defaultMessage: 'Users with a specific email domain',
- },
- AllowedDomainsInfo: {
- id: 'general_tab.AllowedDomainsInfo',
- defaultMessage: 'When enabled, users can only join the team if their email matches a specific domain (e.g. "mattermost.org")',
- },
- AllowedDomains: {
- id: 'general_tab.allowedDomains',
- defaultMessage: 'Allow only users with a specific email domain to join this team',
- },
-});
-
type Props = {
allowedDomains: string[];
setAllowedDomains: (domains: string[]) => void;
@@ -52,15 +37,28 @@ const AllowedDomainsSelect = ({allowedDomains, setAllowedDomains, setHasChanges,
setSaveChangesPanelState('editing');
setAllowedDomains(allowedDomainsOptions?.map((domain) => domain.value) || []);
}, [setAllowedDomains, setHasChanges, setSaveChangesPanelState]);
+
return (
<>
+ }
data-testid='allowedDomainsCheckbox'
className='access-allowed-domains-section'
- title={translations.AllowedDomainsTitle}
- description={translations.AllowedDomainsInfo}
+ title={formatMessage({
+ id: 'general_tab.AllowedDomainsTitle',
+ defaultMessage: 'Users with a specific email domain',
+ })}
+ description={formatMessage({
+ id: 'general_tab.AllowedDomainsInfo',
+ defaultMessage: 'When enabled, users can only join the team if their email matches a specific domain (e.g. "mattermost.org")',
+ })}
descriptionAboveContent={true}
- inputFieldData={{title: translations.AllowedDomains, name: 'name'}}
+ inputFieldData={{name: 'name'}}
inputFieldValue={showAllowedDomains}
handleChange={handleEnableAllowedDomains}
/>
diff --git a/webapp/channels/src/components/team_settings/team_access_tab/invite_section_input.tsx b/webapp/channels/src/components/team_settings/team_access_tab/invite_section_input.tsx
index bc5ce3044d..efc2ac0c2d 100644
--- a/webapp/channels/src/components/team_settings/team_access_tab/invite_section_input.tsx
+++ b/webapp/channels/src/components/team_settings/team_access_tab/invite_section_input.tsx
@@ -24,14 +24,6 @@ const translations = defineMessages({
id: 'team_settings.openInviteDescription.error',
defaultMessage: 'There was an error generating the invite code, please try again',
},
- CodeTitle: {
- id: 'general_tab.codeTitle',
- defaultMessage: 'Invite Code',
- },
- CodeLongDesc: {
- id: 'general_tab.codeLongDesc',
- defaultMessage: 'The Invite Code is part of the unique team invitation link which is sent to members you’re inviting to this team. Regenerating the code creates a new invitation link and invalidates the previous link.',
- },
});
type Props = {
@@ -91,8 +83,15 @@ const InviteSectionInput = ({regenerateTeamInviteId}: Props) => {
return (
void;
};
-const translations = defineMessages({
- OpenInviteText: {
- id: 'general_tab.openInviteText',
- defaultMessage: 'Users on this server',
- },
- OpenInviteDesc: {
- id: 'general_tab.openInviteDesc',
- defaultMessage: 'When enabled, a link to this team will be included on the landing page allowing anyone with an account to join this team. Changing this setting will create a new invitation link and invalidate the previous link.',
- },
- OpenInviteTitle: {
- id: 'general_tab.openInviteTitle',
- defaultMessage: 'Allow only users with a specific email domain to join this team',
- },
-});
-
const OpenInvite = ({isGroupConstrained, allowOpenInvite, setAllowOpenInvite}: Props) => {
const {formatMessage} = useIntl();
if (isGroupConstrained) {
@@ -52,8 +37,14 @@ const OpenInvite = ({isGroupConstrained, allowOpenInvite, setAllowOpenInvite}: P
return (
@@ -63,11 +54,23 @@ const OpenInvite = ({isGroupConstrained, allowOpenInvite, setAllowOpenInvite}: P
return (
+ }
+ inputFieldData={{name: 'name'}}
inputFieldValue={allowOpenInvite}
handleChange={setAllowOpenInvite}
- title={translations.OpenInviteText}
- description={translations.OpenInviteDesc}
+ title={formatMessage({
+ id: 'general_tab.openInviteText',
+ defaultMessage: 'Users on this server',
+ })}
+ description={formatMessage({
+ id: 'general_tab.openInviteDesc',
+ defaultMessage: 'When enabled, a link to this team will be included on the landing page allowing anyone with an account to join this team. Changing this setting will create a new invitation link and invalidate the previous link.',
+ })}
descriptionAboveContent={true}
/>
);
diff --git a/webapp/channels/src/components/team_settings/team_info_tab/team_description_section.tsx b/webapp/channels/src/components/team_settings/team_info_tab/team_description_section.tsx
index cc3891c225..61a52a5114 100644
--- a/webapp/channels/src/components/team_settings/team_info_tab/team_description_section.tsx
+++ b/webapp/channels/src/components/team_settings/team_info_tab/team_description_section.tsx
@@ -3,7 +3,7 @@
import React, {useCallback} from 'react';
import type {ChangeEvent} from 'react';
-import {defineMessages, useIntl} from 'react-intl';
+import {useIntl} from 'react-intl';
import type {Team} from '@mattermost/types/teams';
@@ -12,13 +12,6 @@ import BaseSettingItem, {type BaseSettingItemProps} from 'components/widgets/mod
import Constants from 'utils/constants';
-const translations = defineMessages({
- TeamDescriptionInfo: {
- id: 'general_tab.teamDescriptionInfo',
- defaultMessage: 'Team description provides additional information to help users select the right team. Maximum of 50 characters.',
- },
-});
-
type Props = {
handleDescriptionChanges: (name: string) => void;
description: Team['description'];
@@ -47,7 +40,10 @@ const TeamDescriptionSection = ({handleDescriptionChanges, clientError, descript
return (
void;
name: Team['display_name'];
@@ -48,8 +37,14 @@ const TeamNameSection = ({clientError, handleNameChanges, name}: Props) => {
return (
diff --git a/webapp/channels/src/components/team_settings/team_info_tab/team_picture_section.tsx b/webapp/channels/src/components/team_settings/team_info_tab/team_picture_section.tsx
index dcf1c94ee8..ce672b4e87 100644
--- a/webapp/channels/src/components/team_settings/team_info_tab/team_picture_section.tsx
+++ b/webapp/channels/src/components/team_settings/team_info_tab/team_picture_section.tsx
@@ -2,7 +2,7 @@
// See LICENSE.txt for license information.
import React, {type ChangeEvent, useRef, useState, useEffect, useCallback} from 'react';
-import {defineMessages, useIntl} from 'react-intl';
+import {useIntl} from 'react-intl';
import {TrashCanOutlineIcon} from '@mattermost/compass-icons/components';
import type {Team} from '@mattermost/types/teams';
@@ -14,19 +14,8 @@ import type {BaseSettingItemProps} from 'components/widgets/modals/components/ba
import Constants from 'utils/constants';
import * as FileUtils from 'utils/file_utils';
import {imageURLForTeam} from 'utils/utils';
-import './team_picture_section.scss';
-const translations = defineMessages({
- Title: {
- id: 'setting_picture.title',
- defaultMessage: 'Team Icon',
- },
- Profile: {
- id: 'setting_picture.help.profile',
- defaultMessage: 'Upload a picture in BMP, JPG, JPEG, or PNG format. Maximum file size: {max}',
- values: {max: '50MB'},
- },
-});
+import './team_picture_section.scss';
type Props = {
team: Team;
@@ -168,8 +157,19 @@ const TeamPictureSection = ({team, file, teamName, disabled, onFileChange, onRem
return (
- {formatMessage({id: title.id, defaultMessage: title.defaultMessage}, title.values)}
+ {title}
);
- const Description = description && (
+ const descriptionComponent = description && (
- {formatMessage({id: description.id, defaultMessage: description.defaultMessage}, description.values)}
+ {description}
);
@@ -57,19 +58,17 @@ function BaseSettingItem({title, description, content, className, error, descrip
);
- const getClassName = classNames('mm-modal-generic-section-item', className);
-
return (
-
- {Title}
- {descriptionAboveContent ? Description : undefined}
+
+ {titleComponent}
+ {descriptionAboveContent ? descriptionComponent : undefined}
{content}
- {descriptionAboveContent ? undefined : Description}
+ {descriptionAboveContent ? undefined : descriptionComponent}
{Error}
);
diff --git a/webapp/channels/src/components/widgets/modals/components/checkbox_setting_item.tsx b/webapp/channels/src/components/widgets/modals/components/checkbox_setting_item.tsx
index aef4002aaa..15838c7f7f 100644
--- a/webapp/channels/src/components/widgets/modals/components/checkbox_setting_item.tsx
+++ b/webapp/channels/src/components/widgets/modals/components/checkbox_setting_item.tsx
@@ -1,35 +1,40 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
+import type {ReactNode} from 'react';
import React from 'react';
-import {FormattedMessage} from 'react-intl';
-import type {MessageDescriptor} from 'react-intl';
import type {BaseSettingItemProps} from './base_setting_item';
import BaseSettingItem from './base_setting_item';
export type FieldsetCheckbox = {
dataTestId?: string;
- title: MessageDescriptor;
name: string;
}
type Props = BaseSettingItemProps & {
inputFieldData: FieldsetCheckbox;
inputFieldValue: boolean;
+
+ /**
+ * The title of the checkbox input field, pass in FormattedMessage component for styling compatibility
+ */
+ inputFieldTitle: ReactNode;
handleChange: (e: boolean) => void;
className?: string;
descriptionAboveContent?: boolean;
}
-function CheckboxSettingItem({
+
+export default function CheckboxSettingItem({
title,
description,
inputFieldData,
inputFieldValue,
+ inputFieldTitle,
handleChange,
className,
descriptionAboveContent = false,
-}: Props): JSX.Element {
+}: Props) {
const content = (
handleChange(e.target.checked)}
/>
-
+ {inputFieldTitle}
-
);
+
return (
);
}
-
-export default CheckboxSettingItem;
diff --git a/webapp/channels/src/components/widgets/modals/components/modal_header.scss b/webapp/channels/src/components/widgets/modals/components/modal_header.scss
index 9382264606..8304a05063 100644
--- a/webapp/channels/src/components/widgets/modals/components/modal_header.scss
+++ b/webapp/channels/src/components/widgets/modals/components/modal_header.scss
@@ -15,6 +15,7 @@
font-style: normal;
font-weight: 600;
line-height: 28px;
+ white-space: nowrap;
}
&__vertical-divider {
@@ -42,28 +43,6 @@
flex: 1 1 auto;
align-items: center;
justify-content: flex-end;
- color: rgba(var(--center-channel-color-rgb), 0.56);
- gap: 24px;
- }
-
- &__close-btn {
- display: flex;
- overflow: hidden;
- width: 40px;
- height: 40px;
- align-items: center;
- justify-content: center;
- border: unset;
- border-radius: 4px;
- margin-left: 8px;
- background: transparent;
- color: rgba(var(--center-channel-color-rgb), 0.56);
-
- &:hover,
- &.active {
- background: rgba(var(--center-channel-color-rgb), 0.08);
- color: rgba(var(--center-channel-color-rgb), 0.72);
- }
}
@media screen and (max-width: 768px) {
diff --git a/webapp/channels/src/components/widgets/modals/components/modal_header.tsx b/webapp/channels/src/components/widgets/modals/components/modal_header.tsx
index 38ef724130..f04a2778b1 100644
--- a/webapp/channels/src/components/widgets/modals/components/modal_header.tsx
+++ b/webapp/channels/src/components/widgets/modals/components/modal_header.tsx
@@ -3,7 +3,6 @@
import React from 'react';
-import {CloseIcon} from '@mattermost/compass-icons/components';
import './modal_header.scss';
type Props = {
@@ -29,11 +28,8 @@ function ModalHeader({id, title, subtitle, handleClose}: Props) {
className='mm-modal-header__ctr'
onClick={handleClose}
>
-
-
+
+
diff --git a/webapp/channels/src/components/widgets/modals/components/modal_section.scss b/webapp/channels/src/components/widgets/modals/components/modal_section.scss
index e8147bc95a..2c5a5a4266 100644
--- a/webapp/channels/src/components/widgets/modals/components/modal_section.scss
+++ b/webapp/channels/src/components/widgets/modals/components/modal_section.scss
@@ -2,46 +2,41 @@
display: flex;
flex-direction: column;
- &__info-ctr {
+ .modalSectionHeader {
display: flex;
flex-direction: column;
- margin-bottom: 8px;
gap: 8px;
+ margin-block-end: 24px;
+
+ .modalSectionTitle {
+ display: flex;
+ align-items: center;
+ padding: 0;
+ margin: 0;
+ color: var(--center-channel-color);
+ font-family: "Metropolis", sans-serif;
+ font-size: 16px;
+ font-style: normal;
+ font-weight: 600;
+ gap: 8px;
+ line-height: 24px;
+ }
+
+ .modalSectionDescription {
+ display: flex;
+ align-items: center;
+ padding: 0;
+ margin: 0;
+ color: rgba(var(--center-channel-color-rgb), 0.64);
+ font-family: "Open Sans", sans-serif;
+ font-size: 12px;
+ font-style: normal;
+ font-weight: 400;
+ line-height: 16px;
+ }
}
- &__title {
- display: flex;
- align-items: center;
- padding: 0;
- margin: 0;
- color: var(--center-channel-color);
- font-family: 'Metropolis', sans-serif;
- font-size: 16px;
- font-style: normal;
- font-weight: 600;
- line-height: 24px;
- }
-
- &__row {
- display: flex;
- align-items: center;
- gap: 8px;
- }
-
- &__description {
- display: flex;
- align-items: center;
- padding: 0;
- margin: 0;
- color: rgba(var(--center-channel-color-rgb), 0.64);
- font-family: 'Open Sans', sans-serif;
- font-size: 12px;
- font-style: normal;
- font-weight: 400;
- line-height: 16px;
- }
-
- &__content {
+ .modalSectionContent {
display: flex;
flex-direction: column;
gap: 24px;
diff --git a/webapp/channels/src/components/widgets/modals/components/modal_section.tsx b/webapp/channels/src/components/widgets/modals/components/modal_section.tsx
index 016d8c8691..1f26b7a08c 100644
--- a/webapp/channels/src/components/widgets/modals/components/modal_section.tsx
+++ b/webapp/channels/src/components/widgets/modals/components/modal_section.tsx
@@ -2,14 +2,13 @@
// See LICENSE.txt for license information.
import React from 'react';
-import type {MessageDescriptor} from 'react-intl';
-import {useIntl} from 'react-intl';
+import type {ReactNode} from 'react';
import './modal_section.scss';
type Props = {
- title?: MessageDescriptor;
- description?: MessageDescriptor;
+ title?: ReactNode;
+ description?: ReactNode;
content: JSX.Element;
titleSuffix?: JSX.Element;
};
@@ -19,46 +18,29 @@ function ModalSection({
description,
content,
titleSuffix,
-}: Props): JSX.Element {
- const {formatMessage} = useIntl();
- const titleContent = title ? (
-
- {formatMessage({id: title.id, defaultMessage: title.defaultMessage})}
+}: Props) {
+ const titleComponent = title && (
+
+ {title}
+ {titleSuffix}
- ) : undefined;
+ );
- const descriptionContent = description && (
-
- {formatMessage({id: description.id, defaultMessage: description.defaultMessage})}
+ const descriptionComponent = description && (
+
+ {description}
);
- function titleRow() {
- if (titleSuffix) {
- return (
- {titleContent}
- {titleSuffix}
-
);
- }
- return titleContent;
- }
-
- const titleDescriptionSection = () => {
- if (title || description) {
- return (
-
- {titleRow()}
- {descriptionContent}
-
- );
- }
- return null;
- };
-
return (
- {titleDescriptionSection()}
-
+ {(title || description) && (
+
+ {titleComponent}
+ {descriptionComponent}
+
+ )}
+
{content}
diff --git a/webapp/channels/src/components/widgets/modals/components/radio_setting_item.tsx b/webapp/channels/src/components/widgets/modals/components/radio_setting_item.tsx
index b7cc551bc9..7671a8891b 100644
--- a/webapp/channels/src/components/widgets/modals/components/radio_setting_item.tsx
+++ b/webapp/channels/src/components/widgets/modals/components/radio_setting_item.tsx
@@ -1,9 +1,8 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
+import type {ReactNode} from 'react';
import React from 'react';
-import type {MessageDescriptor} from 'react-intl';
-import {FormattedMessage} from 'react-intl';
import type {BaseSettingItemProps} from './base_setting_item';
import BaseSettingItem from './base_setting_item';
@@ -11,7 +10,7 @@ import BaseSettingItem from './base_setting_item';
export type FieldsetRadio = {
options: Array<{
dataTestId?: string;
- title: MessageDescriptor;
+ title: ReactNode;
name: string;
key: string;
value: string;
@@ -20,13 +19,16 @@ export type FieldsetRadio = {
}
type Props = BaseSettingItemProps & {
+ className?: string;
inputFieldData: FieldsetRadio;
inputFieldValue: string;
handleChange: (e: React.ChangeEvent
) => void;
}
+
function RadioSettingItem({
title,
description,
+ className,
inputFieldData,
inputFieldValue,
handleChange,
@@ -46,10 +48,7 @@ function RadioSettingItem({
value={option.value}
onChange={handleChange}
/>
-
+ {option.title}
{option.suffix}
);
@@ -62,6 +61,7 @@ function RadioSettingItem({
);
return (