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 | 65 ++- .../modals/components/modal_section.tsx | 56 +-- .../modals/components/radio_setting_item.tsx | 14 +- 25 files changed, 609 insertions(+), 856 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 c34cb4022d..6f1aa45dca 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 82a0e47483..0000000000 --- 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 8989ce39cd..0113d7e89c 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 654a009173..dd56cdd317 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 0000000000..a399f5c53e --- /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 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

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 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) { }
); - 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 (