From 959e33303184b6b285cb9a4a0db2a74094655c23 Mon Sep 17 00:00:00 2001 From: M-ZubairAhmed Date: Thu, 21 Mar 2024 10:25:10 +0000 Subject: [PATCH] [MM-57081] Spacing, font and cutoff issues on Channel notifications preferences modal (#26478) --- .../channel_notifications_spec.js | 33 +- .../channels/src/components/alert_banner.tsx | 147 ------- .../__snapshots__/index.test.tsx.snap} | 0 .../{ => alert_banner}/alert_banner.scss | 1 - .../index.test.tsx} | 2 +- .../src/components/alert_banner/index.tsx | 139 +++++++ .../channel_notifications_modal.test.tsx.snap | 381 +++++++----------- .../channel_notifications_modal.scss | 44 +- .../channel_notifications_modal.tsx | 136 +++++-- .../channel_notifications_modal/utils.tsx | 186 ++------- .../file_limit_sticky_banner/index.tsx | 9 +- .../allowed_domains_select.tsx | 36 +- .../team_access_tab/invite_section_input.tsx | 19 +- .../team_access_tab/open_invite.tsx | 45 ++- .../team_description_section.tsx | 14 +- .../team_info_tab/team_name_section.tsx | 23 +- .../team_info_tab/team_picture_section.tsx | 30 +- .../modals/components/base_setting_item.scss | 7 +- .../modals/components/base_setting_item.tsx | 23 +- .../components/checkbox_setting_item.tsx | 24 +- .../modals/components/modal_header.scss | 23 +- .../modals/components/modal_header.tsx | 8 +- .../modals/components/modal_section.scss | 61 ++- .../modals/components/modal_section.tsx | 56 +-- .../modals/components/radio_setting_item.tsx | 14 +- 25 files changed, 607 insertions(+), 854 deletions(-) delete mode 100644 webapp/channels/src/components/alert_banner.tsx rename webapp/channels/src/components/{__snapshots__/alert_banner.test.tsx.snap => alert_banner/__snapshots__/index.test.tsx.snap} (100%) rename webapp/channels/src/components/{ => alert_banner}/alert_banner.scss (99%) rename webapp/channels/src/components/{alert_banner.test.tsx => alert_banner/index.test.tsx} (97%) create mode 100644 webapp/channels/src/components/alert_banner/index.tsx diff --git a/e2e-tests/cypress/tests/integration/channels/collapsed_reply_threads/channel_notifications_spec.js b/e2e-tests/cypress/tests/integration/channels/collapsed_reply_threads/channel_notifications_spec.js index c34cb4022de8..6f1aa45dca80 100644 --- a/e2e-tests/cypress/tests/integration/channels/collapsed_reply_threads/channel_notifications_spec.js +++ b/e2e-tests/cypress/tests/integration/channels/collapsed_reply_threads/channel_notifications_spec.js @@ -53,10 +53,15 @@ describe('CRT Desktop notifications', () => { cy.visit(testChannelUrl); cy.uiOpenChannelMenu('Notification Preferences'); - cy.get('[data-testid="muteChannel"]').click().then(() => { - cy.get('.AlertBanner--app').should('be.visible'); - }); - cy.get('.channel-notifications-settings-modal__save-btn').should('be.visible').click(); + + // # Click on Mute Channel to Unmute Channel + cy.findByText('Mute channel').should('be.visible').click({force: true}); + + // * Verify that channel is muted alert is visible + cy.findByText('This channel is muted').should('be.visible'); + + // # Save the changes + cy.findByText('Save').should('be.visible').click(); // Setup notification spy spyNotificationAs('notifySpy', 'granted'); @@ -64,8 +69,8 @@ describe('CRT Desktop notifications', () => { // # Set users notification settings cy.uiOpenChannelMenu('Notification Preferences'); - // # click on Mute Channel to Unmute Channel - cy.get('[data-testid="muteChannel"]').click(); + // # Click on Mute Channel to Unmute Channel + cy.findByText('Mute channel').should('be.visible').click({force: true}); // # Click "Desktop Notifications" cy.findByText('Desktop Notifications').should('be.visible'); @@ -83,15 +88,16 @@ describe('CRT Desktop notifications', () => { cy.get('.channel-notifications-settings-modal__body').scrollTo('center').get('#desktopNotification-none').should('be.visible').click(); cy.get('.channel-notifications-settings-modal__body').get('#desktopNotification-none').should('be.checked'); - // # click on Save button - cy.get('.channel-notifications-settings-modal__save-btn').should('be.visible').click(); + // # Save the changes + cy.findByText('Save').should('be.visible').click(); // # Set users notification settings cy.uiOpenChannelMenu('Notification Preferences'); cy.get('.channel-notifications-settings-modal__body').scrollTo('center').get('#desktopNotification-none').should('be.checked'); cy.get('.channel-notifications-settings-modal__body').get('#desktopNotification-all').scrollIntoView().should('be.visible').click(); - cy.get('.channel-notifications-settings-modal__save-btn').should('be.visible').click(); + // # Save the changes + cy.findByText('Save').should('be.visible').click(); // # Post a root message as other user cy.postMessageAs({sender, message: 'This is a not followed root message', channelId: testChannelId, rootId: ''}).then(({id: postId}) => { @@ -137,6 +143,7 @@ describe('CRT Desktop notifications', () => { it('MM-T4417_2 Click on sameMobileSettingsDesktop and check if additional settings still appears', () => { cy.visit(testChannelUrl); cy.uiOpenChannelMenu('Notification Preferences'); + cy.get('.channel-notifications-settings-modal__body').scrollTo('center').get('#desktopNotification-mention').should('be.visible').click().then(() => { cy.get('[data-testid="desktopReplyThreads"]').should('be.visible').click(); }); @@ -157,8 +164,8 @@ describe('CRT Desktop notifications', () => { cy.get('[data-testid="autoFollowThreads"]').should('be.visible').click(); - // # click on Save button - cy.get('.channel-notifications-settings-modal__save-btn').should('be.visible').click(); + // # Save the changes + cy.findByText('Save').should('be.visible').click(); }); it('MM-T4417_3 Trigger notifications only on mention replies when channel setting is unchecked', () => { @@ -168,7 +175,9 @@ describe('CRT Desktop notifications', () => { spyNotificationAs('notifySpy', 'granted'); cy.uiOpenChannelMenu('Notification Preferences'); cy.get('.channel-notifications-settings-modal__body').scrollTo('center').get('#desktopNotification-mention').should('be.visible').click(); - cy.get('.channel-notifications-settings-modal__save-btn').should('be.visible').click(); + + // # Save the changes + cy.findByText('Save').should('be.visible').click(); // # Post a root message as other user cy.postMessageAs({sender, message: 'This is a not followed root message', channelId: testChannelId, rootId: ''}).then(({id: postId}) => { diff --git a/webapp/channels/src/components/alert_banner.tsx b/webapp/channels/src/components/alert_banner.tsx deleted file mode 100644 index 82a0e47483a7..000000000000 --- a/webapp/channels/src/components/alert_banner.tsx +++ /dev/null @@ -1,147 +0,0 @@ -// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. -// See LICENSE.txt for license information. - -import classNames from 'classnames'; -import React, {useCallback, useState} from 'react'; -import {useIntl} from 'react-intl'; - -import { - AlertOutlineIcon, - CheckIcon, - CloseIcon, - InformationOutlineIcon, -} from '@mattermost/compass-icons/components'; - -import OverlayTrigger from 'components/overlay_trigger'; -import Tooltip from 'components/tooltip'; - -import Constants from 'utils/constants'; - -import './alert_banner.scss'; - -export type ModeType = 'danger' | 'warning' | 'info' | 'success'; - -export type AlertBannerProps = { - id?: string; - mode: ModeType; - title?: React.ReactNode; - customIcon?: React.ReactNode; - message?: React.ReactNode; - children?: React.ReactNode; - className?: string; - hideIcon?: boolean; - actionButtonLeft?: React.ReactNode; - actionButtonRight?: React.ReactNode; - footerMessage?: React.ReactNode; - closeBtnTooltip?: React.ReactNode; - onDismiss?: () => void; - variant?: 'sys' | 'app'; -} - -const AlertBanner = ({ - id, - mode, - title, - customIcon, - message, - className, - variant = 'sys', - onDismiss, - actionButtonLeft, - actionButtonRight, - closeBtnTooltip, - footerMessage, - hideIcon, - children, -}: AlertBannerProps) => { - const {formatMessage} = useIntl(); - const closeText = formatMessage({id: 'alert_banner.tooltipCloseBtn', defaultMessage: 'Close'}); - const [tooltipId] = useState(`alert_banner_close_btn_tooltip_${Math.random()}`); - - const bannerIcon = useCallback(() => { - if (customIcon) { - return customIcon; - } - if (mode === 'danger' || mode === 'warning') { - return ( - ); - } else if (mode === 'success') { - return ( - ); - } - return ( - ); - }, [mode, customIcon]); - - return ( -
- {!hideIcon && ( -
- {bannerIcon()} -
- )} -
- {title &&
{title}
} - {message && ( -
- {message} -
- )} - {children} - {(actionButtonLeft || actionButtonRight) && ( -
- {actionButtonLeft} - {actionButtonRight} -
- )} - { - footerMessage && ( -
- {footerMessage} -
- ) - } -
- {onDismiss && ( - {closeText} - )} - > - - - )} -
- ); -}; - -export default AlertBanner; diff --git a/webapp/channels/src/components/__snapshots__/alert_banner.test.tsx.snap b/webapp/channels/src/components/alert_banner/__snapshots__/index.test.tsx.snap similarity index 100% rename from webapp/channels/src/components/__snapshots__/alert_banner.test.tsx.snap rename to webapp/channels/src/components/alert_banner/__snapshots__/index.test.tsx.snap diff --git a/webapp/channels/src/components/alert_banner.scss b/webapp/channels/src/components/alert_banner/alert_banner.scss similarity index 99% rename from webapp/channels/src/components/alert_banner.scss rename to webapp/channels/src/components/alert_banner/alert_banner.scss index 8989ce39cd3f..0113d7e89ca0 100644 --- a/webapp/channels/src/components/alert_banner.scss +++ b/webapp/channels/src/components/alert_banner/alert_banner.scss @@ -3,7 +3,6 @@ .AlertBanner { display: flex; - overflow: hidden; align-items: flex-start; padding: 14px; border: 1px solid; diff --git a/webapp/channels/src/components/alert_banner.test.tsx b/webapp/channels/src/components/alert_banner/index.test.tsx similarity index 97% rename from webapp/channels/src/components/alert_banner.test.tsx rename to webapp/channels/src/components/alert_banner/index.test.tsx index 654a0091732c..dd56cdd31706 100644 --- a/webapp/channels/src/components/alert_banner.test.tsx +++ b/webapp/channels/src/components/alert_banner/index.test.tsx @@ -4,7 +4,7 @@ import {shallow} from 'enzyme'; import React from 'react'; -import AlertBanner from './alert_banner'; +import AlertBanner from 'components/alert_banner'; describe('Components/AlertBanner', () => { test('should match snapshot', () => { diff --git a/webapp/channels/src/components/alert_banner/index.tsx b/webapp/channels/src/components/alert_banner/index.tsx new file mode 100644 index 000000000000..a399f5c53e08 --- /dev/null +++ b/webapp/channels/src/components/alert_banner/index.tsx @@ -0,0 +1,139 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +import classNames from 'classnames'; +import type {ReactNode} from 'react'; +import React, {useMemo} from 'react'; +import {useIntl} from 'react-intl'; + +import { + AlertOutlineIcon, + CheckIcon, + CloseIcon, + InformationOutlineIcon, +} from '@mattermost/compass-icons/components'; + +import WithTooltip from 'components/with_tooltip'; + +import './alert_banner.scss'; + +export type ModeType = 'danger' | 'warning' | 'info' | 'success'; + +export type AlertBannerProps = { + id?: string; + mode: ModeType; + title?: ReactNode; + customIcon?: ReactNode; + message?: ReactNode; + children?: ReactNode; + className?: string; + hideIcon?: boolean; + actionButtonLeft?: ReactNode; + actionButtonRight?: ReactNode; + footerMessage?: ReactNode; + closeBtnTooltip?: string; + onDismiss?: () => void; + variant?: 'sys' | 'app'; +} + +const AlertBanner = ({ + id, + mode, + title, + customIcon, + message, + className, + variant = 'sys', + onDismiss, + actionButtonLeft, + actionButtonRight, + closeBtnTooltip, + footerMessage, + hideIcon, + children, +}: AlertBannerProps) => { + const {formatMessage} = useIntl(); + + const bannerIcon = useMemo(() => { + if (customIcon) { + return customIcon; + } + + if (mode === 'danger' || mode === 'warning') { + return ; + } else if (mode === 'success') { + return ; + } + return ; + }, [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 d00414fa8de4..0b27528c3983 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

Mute channel -

- 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 -
+

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 { > @@ -496,20 +476,11 @@ Object { class="mm-modal-header__ctr" >
@@ -520,16 +491,16 @@ Object { class="mm-modal-generic-section" >

Mute or ignore

Mute channel -

- 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 -
+

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 { > @@ -957,20 +917,11 @@ Object { class="mm-modal-header__ctr" >
@@ -981,16 +932,16 @@ Object { class="mm-modal-generic-section" >

Mute or ignore

Mute channel -

- 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 -
+

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 { > @@ -1401,20 +1341,11 @@ Object { class="mm-modal-header__ctr" >
@@ -1425,16 +1356,16 @@ Object { class="mm-modal-generic-section" >

Mute or ignore

Mute channel -

- 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 -

@@ -1666,20 +1596,11 @@ Object { class="mm-modal-header__ctr" >
@@ -1690,16 +1611,16 @@ Object { class="mm-modal-generic-section" >

Mute or ignore

Mute channel -

- 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 -
+

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 { > @@ -2054,20 +1964,11 @@ Object { class="mm-modal-header__ctr" >
@@ -2078,16 +1979,16 @@ Object { class="mm-modal-generic-section" >

Mute or ignore

Mute channel -

- 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 -
+

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 { > 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 84d87c5990c1..ee01847fc267 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 38f52bda616a..1c12e76c5cb0 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) { }
); - 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 aef4002aaa39..15838c7f7f51 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 93822646069f..8304a0506310 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 38ef72413037..f04a2778b168 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 e8147bc95acc..2c5a5a42662b 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; - } - - &__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; - } + margin-block-end: 24px; - &__row { - display: flex; - align-items: center; - gap: 8px; - } + .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; + } - &__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; + .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; + } } - &__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 016d8c869160..1f26b7a08cc7 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 b7cc551bc9b6..7671a8891b26 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 (