From 00655defd48fefab61d6f93dd66621e8b21fa16e Mon Sep 17 00:00:00 2001 From: Devin Binnie Date: Fri, 24 Jul 2020 10:39:45 -0400 Subject: [PATCH 1/8] Hooked up the sidebar next steps bar and some fixes --- components/sidebar/sidebar.tsx | 2 +- .../sidebar/sidebar_next_steps/index.ts | 21 +++++++++++++++++++ .../sidebar_next_steps.scss | 10 ++++----- .../sidebar_next_steps/sidebar_next_steps.tsx | 12 +++++++---- 4 files changed, 35 insertions(+), 10 deletions(-) create mode 100644 components/sidebar/sidebar_next_steps/index.ts diff --git a/components/sidebar/sidebar.tsx b/components/sidebar/sidebar.tsx index 92942319d508..8c92b32f4345 100644 --- a/components/sidebar/sidebar.tsx +++ b/components/sidebar/sidebar.tsx @@ -21,7 +21,7 @@ import SidebarHeader from './sidebar_header'; import ChannelNavigator from './channel_navigator'; import ChannelFilter from './channel_filter'; import SidebarCategoryList from './sidebar_category_list'; -import SidebarNextSteps from './sidebar_next_steps/sidebar_next_steps'; +import SidebarNextSteps from './sidebar_next_steps'; import SidebarWhatsNewModal from './sidebar_whats_new_modal'; type Props = { diff --git a/components/sidebar/sidebar_next_steps/index.ts b/components/sidebar/sidebar_next_steps/index.ts new file mode 100644 index 000000000000..23305244ebe0 --- /dev/null +++ b/components/sidebar/sidebar_next_steps/index.ts @@ -0,0 +1,21 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +import {connect} from 'react-redux'; + +import {makeGetCategory} from 'mattermost-redux/selectors/entities/preferences'; + +import {GlobalState} from 'types/store'; +import {Preferences} from 'utils/constants'; + +import SidebarNextSteps from './sidebar_next_steps'; + +function makeMapStateToProps() { + const getCategory = makeGetCategory(); + + return (state: GlobalState) => ({ + preferences: getCategory(state, Preferences.RECOMMENDED_NEXT_STEPS), + }); +} + +export default connect(makeMapStateToProps)(SidebarNextSteps); diff --git a/components/sidebar/sidebar_next_steps/sidebar_next_steps.scss b/components/sidebar/sidebar_next_steps/sidebar_next_steps.scss index 9f7d06c976cc..d1677958ce08 100644 --- a/components/sidebar/sidebar_next_steps/sidebar_next_steps.scss +++ b/components/sidebar/sidebar_next_steps/sidebar_next_steps.scss @@ -2,8 +2,8 @@ width: 100%; color: var(--sidebar-text); padding: 8px 16px 18px 14px; - position: absolute; - bottom: 0; + align-self: flex-end; + background-color: var(--sidebar-bg); &.active { background-color: var(--sidebar-text-hover-bg); @@ -39,7 +39,7 @@ margin-left: auto; font-size: 14.4px; line-height: 14px; - + align-self: center; width: 28px; height: 28px; @@ -56,7 +56,7 @@ &:hover { background-color: var(--sidebar-text-hover-bg); - i { + i { opacity: 1; } } @@ -82,4 +82,4 @@ border-radius: 4px; background-color: var(--sidebar-text); } -} \ No newline at end of file +} diff --git a/components/sidebar/sidebar_next_steps/sidebar_next_steps.tsx b/components/sidebar/sidebar_next_steps/sidebar_next_steps.tsx index 2b6f21ff44c3..379958b21f2c 100644 --- a/components/sidebar/sidebar_next_steps/sidebar_next_steps.tsx +++ b/components/sidebar/sidebar_next_steps/sidebar_next_steps.tsx @@ -4,13 +4,16 @@ import React from 'react'; import {FormattedMessage} from 'react-intl'; +import {PreferenceType} from 'mattermost-redux/types/preferences'; + import FormattedMarkdownMessage from 'components/formatted_markdown_message.jsx'; +import {Steps} from 'components/next_steps_view/steps'; import ProgressBar from 'components/progress_bar'; import './sidebar_next_steps.scss'; type Props = { - + preferences: PreferenceType[]; }; type State = { @@ -33,7 +36,8 @@ export default class SidebarNextSteps extends React.PureComponent render() { // TODO: Temporary values - const total = 3; + const total = Steps.length; + const complete = this.props.preferences.filter((pref) => pref.value).length; return (
@@ -57,7 +61,7 @@ export default class SidebarNextSteps extends React.PureComponent id='sidebar_next_steps.stepsComplete' defaultMessage='{complete} / {total} steps complete' values={{ - complete: this.state.complete, + complete, total, }} /> @@ -65,7 +69,7 @@ export default class SidebarNextSteps extends React.PureComponent
From b3949f359726a6465854b9a31603887020d1bc01 Mon Sep 17 00:00:00 2001 From: Devin Binnie Date: Fri, 24 Jul 2020 14:17:48 -0400 Subject: [PATCH 2/8] Integration of state into app for next steps view, close next steps view modal preliminary --- actions/views/next_steps.ts | 11 ++++ components/channel_view/channel_view.jsx | 21 ++++++- components/channel_view/channel_view.test.jsx | 2 + components/channel_view/index.js | 3 + components/next_steps_view/index.ts | 2 + .../next_steps_view/next_steps_view.test.tsx | 1 + .../next_steps_view/next_steps_view.tsx | 1 + components/next_steps_view/steps.ts | 6 +- .../__snapshots__/sidebar.test.tsx.snap | 8 +-- .../close_next_steps_modal.scss | 0 .../close_next_steps_modal.tsx | 46 ++++++++++++++++ .../sidebar/sidebar_next_steps/index.ts | 22 +++++++- .../sidebar_next_steps.scss | 1 + .../sidebar_next_steps/sidebar_next_steps.tsx | 55 +++++++++++++++++-- i18n/en.json | 3 + reducers/views/index.js | 2 + reducers/views/next_steps.ts | 25 +++++++++ types/store/index.ts | 4 ++ utils/constants.jsx | 3 + 19 files changed, 203 insertions(+), 13 deletions(-) create mode 100644 actions/views/next_steps.ts create mode 100644 components/sidebar/sidebar_next_steps/close_next_steps_modal.scss create mode 100644 components/sidebar/sidebar_next_steps/close_next_steps_modal.tsx create mode 100644 reducers/views/next_steps.ts diff --git a/actions/views/next_steps.ts b/actions/views/next_steps.ts new file mode 100644 index 000000000000..1115df66e16a --- /dev/null +++ b/actions/views/next_steps.ts @@ -0,0 +1,11 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +import {ActionTypes} from 'utils/constants'; + +export function setShowNextStepsView(show: boolean) { + return { + type: ActionTypes.SET_SHOW_NEXT_STEPS_VIEW, + show, + }; +} diff --git a/components/channel_view/channel_view.jsx b/components/channel_view/channel_view.jsx index ddac5f4f4f3e..90ca7d6e3f2a 100644 --- a/components/channel_view/channel_view.jsx +++ b/components/channel_view/channel_view.jsx @@ -29,10 +29,12 @@ export default class ChannelView extends React.PureComponent { }).isRequired, showTutorial: PropTypes.bool.isRequired, showNextSteps: PropTypes.bool.isRequired, + showNextStepsEphemeral: PropTypes.bool.isRequired, channelIsArchived: PropTypes.bool.isRequired, viewArchivedChannels: PropTypes.bool.isRequired, actions: PropTypes.shape({ goToLastViewedChannel: PropTypes.func.isRequired, + setShowNextStepsView: PropTypes.func.isRequired, }), }; @@ -54,7 +56,7 @@ export default class ChannelView extends React.PureComponent { const focusedPostId = props.match.params.postid; if (props.match.url !== state.url && props.channelId !== state.channelId) { - updatedState = {deferredPostView: ChannelView.createDeferredPostView(), url: props.match.url, focusedPostId, showNextSteps: false}; + updatedState = {deferredPostView: ChannelView.createDeferredPostView(), url: props.match.url, focusedPostId}; } if (props.channelId !== state.channelId) { @@ -65,6 +67,10 @@ export default class ChannelView extends React.PureComponent { updatedState = {...updatedState, focusedPostId}; } + if (props.showNextSteps !== state.showNextSteps) { + updatedState = {...updatedState, showNextSteps: props.showNextSteps}; + } + if (Object.keys(updatedState).length) { return updatedState; } @@ -79,7 +85,6 @@ export default class ChannelView extends React.PureComponent { url: props.match.url, channelId: props.channelId, deferredPostView: ChannelView.createDeferredPostView(), - showNextSteps: props.showNextSteps, }; } @@ -91,6 +96,12 @@ export default class ChannelView extends React.PureComponent { this.props.actions.goToLastViewedChannel(); } + componentDidMount() { + if (this.props.showNextSteps) { + this.props.actions.setShowNextStepsView(true); + } + } + componentDidUpdate(prevProps) { if (prevProps.channelId !== this.props.channelId || prevProps.channelIsArchived !== this.props.channelIsArchived) { mark('ChannelView#componentDidUpdate'); @@ -114,6 +125,10 @@ export default class ChannelView extends React.PureComponent { this.props.actions.goToLastViewedChannel(); } } + + if (this.props.match.url !== prevProps.match.url && this.props.showNextStepsEphemeral) { + this.props.actions.setShowNextStepsView(false); + } } render() { @@ -126,7 +141,7 @@ export default class ChannelView extends React.PureComponent { ); } - if (this.state.showNextSteps) { + if (this.props.showNextStepsEphemeral) { return ( ); diff --git a/components/channel_view/channel_view.test.jsx b/components/channel_view/channel_view.test.jsx index 21d372eee4cd..69cd2ff735d3 100644 --- a/components/channel_view/channel_view.test.jsx +++ b/components/channel_view/channel_view.test.jsx @@ -17,10 +17,12 @@ describe('components/channel_view', () => { }, showTutorial: false, showNextSteps: false, + showNextStepsEphemeral: false, channelIsArchived: false, viewArchivedChannels: false, actions: { goToLastViewedChannel: jest.fn(), + setShowNextStepsView: jest.fn(), }, }; diff --git a/components/channel_view/index.js b/components/channel_view/index.js index 89438c8c4655..a1ff4b766bfd 100644 --- a/components/channel_view/index.js +++ b/components/channel_view/index.js @@ -16,6 +16,7 @@ import {getDirectTeammate} from 'utils/utils.jsx'; import {TutorialSteps, Preferences} from 'utils/constants'; import {goToLastViewedChannel} from 'actions/views/channel'; +import {setShowNextStepsView} from 'actions/views/next_steps'; import {showNextSteps} from 'components/next_steps_view/steps'; import ChannelView from './channel_view.jsx'; @@ -59,6 +60,7 @@ function mapStateToProps(state) { deactivatedChannel: channel ? getDeactivatedChannel(state, channel.id) : false, showTutorial: enableTutorial && tutorialStep <= TutorialSteps.INTRO_SCREENS, showNextSteps: showNextSteps(state), + showNextStepsEphemeral: state.views.nextSteps.show, channelIsArchived: channel ? channel.delete_at !== 0 : false, viewArchivedChannels, }; @@ -67,6 +69,7 @@ function mapStateToProps(state) { function mapDispatchToProps(dispatch) { return { actions: bindActionCreators({ + setShowNextStepsView, goToLastViewedChannel, }, dispatch), }; diff --git a/components/next_steps_view/index.ts b/components/next_steps_view/index.ts index fb6dc828aeb8..3ff12276ead2 100644 --- a/components/next_steps_view/index.ts +++ b/components/next_steps_view/index.ts @@ -9,6 +9,7 @@ import {getLicense} from 'mattermost-redux/selectors/entities/general'; import {makeGetCategory} from 'mattermost-redux/selectors/entities/preferences'; import {getCurrentUser} from 'mattermost-redux/selectors/entities/users'; +import {setShowNextStepsView} from 'actions/views/next_steps'; import {GlobalState} from 'types/store'; import {Preferences} from 'utils/constants'; @@ -33,6 +34,7 @@ function mapDispatchToProps(dispatch: Dispatch) { return { actions: bindActionCreators({ savePreferences, + setShowNextStepsView, }, dispatch), }; } diff --git a/components/next_steps_view/next_steps_view.test.tsx b/components/next_steps_view/next_steps_view.test.tsx index 532eb36bcd97..2c51f5528219 100644 --- a/components/next_steps_view/next_steps_view.test.tsx +++ b/components/next_steps_view/next_steps_view.test.tsx @@ -12,6 +12,7 @@ describe('components/next_steps_view', () => { preferences: [], skuName: '', actions: { + setShowNextStepsView: jest.fn(), savePreferences: jest.fn(), }, }; diff --git a/components/next_steps_view/next_steps_view.tsx b/components/next_steps_view/next_steps_view.tsx index 2c948d55c864..965d46f83c7b 100644 --- a/components/next_steps_view/next_steps_view.tsx +++ b/components/next_steps_view/next_steps_view.tsx @@ -21,6 +21,7 @@ type Props = { skuName: string; actions: { savePreferences: (userId: string, preferences: PreferenceType[]) => void; + setShowNextStepsView: (show: boolean) => void; }; }; diff --git a/components/next_steps_view/steps.ts b/components/next_steps_view/steps.ts index 4cfe0750ead4..2ed010f7003a 100644 --- a/components/next_steps_view/steps.ts +++ b/components/next_steps_view/steps.ts @@ -3,8 +3,8 @@ import {createSelector} from 'reselect'; import {makeGetCategory} from 'mattermost-redux/selectors/entities/preferences'; -import {GlobalState} from 'mattermost-redux/types/store'; +import {GlobalState} from 'types/store'; import {RecommendedNextSteps, Preferences} from 'utils/constants'; import {localizeMessage} from 'utils/utils'; @@ -44,6 +44,10 @@ const getCategory = makeGetCategory(); export const showNextSteps = createSelector( (state: GlobalState) => getCategory(state, Preferences.RECOMMENDED_NEXT_STEPS), (stepPreferences) => { + if (stepPreferences.some((pref) => pref.name === RecommendedNextSteps.HIDE && pref.value)) { + return false; + } + const checkPref = (step: StepType) => stepPreferences.some((pref) => pref.name === step.id && pref.value); return !Steps.every(checkPref); } diff --git a/components/sidebar/__snapshots__/sidebar.test.tsx.snap b/components/sidebar/__snapshots__/sidebar.test.tsx.snap index 6ab71118f516..d4dec248c321 100644 --- a/components/sidebar/__snapshots__/sidebar.test.tsx.snap +++ b/components/sidebar/__snapshots__/sidebar.test.tsx.snap @@ -33,7 +33,7 @@ exports[`components/sidebar should match snapshot 1`] = ` onDragStart={[Function]} /> - + - + - + - + void; + onCancel: () => void; +} + +export default function CloseNextStepsModal(props: Props) { + const {onConfirm, onCancel} = props; + + return ( + + )} + confirmButtonText={( + + )} + > + + + + + ); +} diff --git a/components/sidebar/sidebar_next_steps/index.ts b/components/sidebar/sidebar_next_steps/index.ts index 23305244ebe0..097bf7df232f 100644 --- a/components/sidebar/sidebar_next_steps/index.ts +++ b/components/sidebar/sidebar_next_steps/index.ts @@ -2,9 +2,15 @@ // See LICENSE.txt for license information. import {connect} from 'react-redux'; +import {Dispatch, bindActionCreators} from 'redux'; +import {savePreferences} from 'mattermost-redux/actions/preferences'; import {makeGetCategory} from 'mattermost-redux/selectors/entities/preferences'; +import {getCurrentUserId} from 'mattermost-redux/selectors/entities/users'; +import {openModal, closeModal} from 'actions/views/modals'; +import {setShowNextStepsView} from 'actions/views/next_steps'; +import {showNextSteps} from 'components/next_steps_view/steps'; import {GlobalState} from 'types/store'; import {Preferences} from 'utils/constants'; @@ -14,8 +20,22 @@ function makeMapStateToProps() { const getCategory = makeGetCategory(); return (state: GlobalState) => ({ + active: state.views.nextSteps.show, + showNextSteps: showNextSteps(state), + currentUserId: getCurrentUserId(state), preferences: getCategory(state, Preferences.RECOMMENDED_NEXT_STEPS), }); } -export default connect(makeMapStateToProps)(SidebarNextSteps); +function mapDispatchToProps(dispatch: Dispatch) { + return { + actions: bindActionCreators({ + savePreferences, + openModal, + closeModal, + setShowNextStepsView, + }, dispatch), + }; +} + +export default connect(makeMapStateToProps, mapDispatchToProps)(SidebarNextSteps); diff --git a/components/sidebar/sidebar_next_steps/sidebar_next_steps.scss b/components/sidebar/sidebar_next_steps/sidebar_next_steps.scss index d1677958ce08..8da96addc155 100644 --- a/components/sidebar/sidebar_next_steps/sidebar_next_steps.scss +++ b/components/sidebar/sidebar_next_steps/sidebar_next_steps.scss @@ -3,6 +3,7 @@ color: var(--sidebar-text); padding: 8px 16px 18px 14px; align-self: flex-end; + position: relative; background-color: var(--sidebar-bg); &.active { diff --git a/components/sidebar/sidebar_next_steps/sidebar_next_steps.tsx b/components/sidebar/sidebar_next_steps/sidebar_next_steps.tsx index 379958b21f2c..89d0517abe67 100644 --- a/components/sidebar/sidebar_next_steps/sidebar_next_steps.tsx +++ b/components/sidebar/sidebar_next_steps/sidebar_next_steps.tsx @@ -3,17 +3,30 @@ import React from 'react'; import {FormattedMessage} from 'react-intl'; +import classNames from 'classnames'; import {PreferenceType} from 'mattermost-redux/types/preferences'; import FormattedMarkdownMessage from 'components/formatted_markdown_message.jsx'; import {Steps} from 'components/next_steps_view/steps'; import ProgressBar from 'components/progress_bar'; +import {ModalIdentifiers, RecommendedNextSteps, Preferences} from 'utils/constants'; import './sidebar_next_steps.scss'; +import CloseNextStepsModal from './close_next_steps_modal'; + type Props = { + active: boolean; + showNextSteps: boolean; + currentUserId: string; preferences: PreferenceType[]; + actions: { + savePreferences: (userId: string, preferences: PreferenceType[]) => void; + openModal: (modalData: {modalId: string; dialogType: any; dialogProps?: any}) => void; + closeModal: (modalId: string) => void; + setShowNextStepsView: (show: boolean) => void; + }; }; type State = { @@ -30,17 +43,51 @@ export default class SidebarNextSteps extends React.PureComponent } closeNextSteps = () => { - // TODO: Using this to test the progress bar for now - this.setState({complete: (this.state.complete + 1) % 4}); + this.props.actions.openModal({ + modalId: ModalIdentifiers.CLOSE_NEXT_STEPS_MODAL, + dialogType: CloseNextStepsModal, + dialogProps: { + onConfirm: this.onConfirmModal, + onCancel: this.onCloseModal, + } + }); + } + + onCloseModal = () => { + this.props.actions.closeModal(ModalIdentifiers.CLOSE_NEXT_STEPS_MODAL); + } + + onConfirmModal = () => { + this.props.actions.savePreferences(this.props.currentUserId, [{ + user_id: this.props.currentUserId, + category: Preferences.RECOMMENDED_NEXT_STEPS, + name: RecommendedNextSteps.HIDE, + value: 'true', + }]); + + this.props.actions.setShowNextStepsView(false); + + this.onCloseModal(); } render() { - // TODO: Temporary values + if (this.props.preferences.some((pref) => pref.name === RecommendedNextSteps.HIDE && pref.value)) { + return null; + } + + if (!this.props.active && !this.props.showNextSteps) { + return null; + } + const total = Steps.length; const complete = this.props.preferences.filter((pref) => pref.value).length; return ( -
+
Date: Fri, 24 Jul 2020 15:44:43 -0400 Subject: [PATCH 3/8] Styling and help arrow for modal --- .../close_next_steps_modal.scss | 58 +++++++++++++++++++ .../close_next_steps_modal.tsx | 57 +++++++++++------- images/close_next_steps_arrow.svg | 5 ++ 3 files changed, 100 insertions(+), 20 deletions(-) create mode 100644 images/close_next_steps_arrow.svg diff --git a/components/sidebar/sidebar_next_steps/close_next_steps_modal.scss b/components/sidebar/sidebar_next_steps/close_next_steps_modal.scss index e69de29bb2d1..6f819ae7121d 100644 --- a/components/sidebar/sidebar_next_steps/close_next_steps_modal.scss +++ b/components/sidebar/sidebar_next_steps/close_next_steps_modal.scss @@ -0,0 +1,58 @@ +.modal-backdrop.in { + clip-path: polygon(0 0, 65px 0, 65px 63px, 305px 63px, 305px 0, 100% 0, 100% 100%, 0 100%); +} + +.CloseNextStepsModal__helpBox { + position: fixed; + top: 16px; + left: 266px; + z-index: 1050; +} + +.CloseNextStepsModal__helpText { + font-weight: 600; + font-size: 12px; + line-height: 16px; + text-align: center; + color: var(--center-channel-bg); + display: block; + width: 188px; + margin-left: -12px; + margin-top: 4px; +} + +.GenericModal__header { + text-align: center; + padding-bottom: 8px; + + h1 { + font-size: 24px; + line-height: 32px; + } +} + +.GenericModal__body { + text-align: center; + color: var(--center-channel-color); +} + +.modal-footer { + text-align: center; +} + +.modal .GenericModal .modal-content { + padding: 40px 36px 24px 36px; +} + +.GenericModal__button { + padding: 13px 20px; + line-height: 14px; + + & +.GenericModal__button { + margin-left: 10px; + } +} + +.modal .GenericModal { + max-width: 514px; +} diff --git a/components/sidebar/sidebar_next_steps/close_next_steps_modal.tsx b/components/sidebar/sidebar_next_steps/close_next_steps_modal.tsx index 9c1a00799ff1..b088c7a99a52 100644 --- a/components/sidebar/sidebar_next_steps/close_next_steps_modal.tsx +++ b/components/sidebar/sidebar_next_steps/close_next_steps_modal.tsx @@ -2,9 +2,11 @@ // See LICENSE.txt for license information. import React from 'react'; +import ReactDOM from 'react-dom'; import {FormattedMessage} from 'react-intl'; import GenericModal from 'components/generic_modal'; +import closeNextStepsArrow from 'images/close_next_steps_arrow.svg'; import './close_next_steps_modal.scss'; @@ -17,30 +19,45 @@ export default function CloseNextStepsModal(props: Props) { const {onConfirm, onCancel} = props; return ( - - )} - confirmButtonText={( - + <> + {ReactDOM.createPortal( +
+ + + + +
, + document.body as HTMLElement )} - > - + + )} + confirmButtonText={( + + )} + > - -
+ + ); } diff --git a/images/close_next_steps_arrow.svg b/images/close_next_steps_arrow.svg new file mode 100644 index 000000000000..508fab2a162e --- /dev/null +++ b/images/close_next_steps_arrow.svg @@ -0,0 +1,5 @@ + + + + + From 1f0cb85eb69a36186c87fdc3c1d88a32f9015a59 Mon Sep 17 00:00:00 2001 From: Devin Binnie Date: Fri, 24 Jul 2020 15:45:36 -0400 Subject: [PATCH 4/8] Missed a translation --- i18n/en.json | 1 + 1 file changed, 1 insertion(+) diff --git a/i18n/en.json b/i18n/en.json index ea3f3dd69e2d..dd4a05828e19 100644 --- a/i18n/en.json +++ b/i18n/en.json @@ -2231,6 +2231,7 @@ "claim.oauth_to_email.title": "Switch {type} Account to Email", "close_next_steps_modal.confirm": "Remove", "close_next_steps_modal.header": "Remove Tip & Next Steps?", + "close_next_steps_modal.helpText": "Access Tips & Next Steps any time through the Help section in the Main Menu", "close_next_steps_modal.mainText": "This will remove this section from your sidebar, but you can access it later in the Help section of the Main Menu.", "combined_system_message.added_to_channel.many_expanded": "{users} and {lastUser} were **added to the channel** by {actor}.", "combined_system_message.added_to_channel.one": "{firstUser} **added to the channel** by {actor}.", From 29c0f9b85723fa752f0f9505a2c9f74e61823816 Mon Sep 17 00:00:00 2001 From: Devin Binnie Date: Mon, 27 Jul 2020 16:08:50 -0400 Subject: [PATCH 5/8] PR feedback --- components/generic_modal.tsx | 3 +- .../close_next_steps_modal.scss | 68 +++++++++++-------- .../close_next_steps_modal.tsx | 19 ++++-- .../sidebar_next_steps/sidebar_next_steps.tsx | 57 ++++++++++++---- i18n/en.json | 6 +- 5 files changed, 103 insertions(+), 50 deletions(-) diff --git a/components/generic_modal.tsx b/components/generic_modal.tsx index 1a8072051a3c..4748dc5c1846 100644 --- a/components/generic_modal.tsx +++ b/components/generic_modal.tsx @@ -9,6 +9,7 @@ import {FormattedMessage} from 'react-intl'; import './generic_modal.scss'; type Props = { + className?: string; onHide: () => void; modalHeaderText: React.ReactNode; show?: boolean; @@ -109,7 +110,7 @@ export default class GenericModal extends React.PureComponent { return ( void; onCancel: () => void; } export default function CloseNextStepsModal(props: Props) { - const {onConfirm, onCancel} = props; + const {onConfirm, onCancel, screenTitle} = props; return ( <> @@ -27,23 +29,30 @@ export default function CloseNextStepsModal(props: Props) { src={closeNextStepsArrow} /> -
, document.body as HTMLElement )} )} confirmButtonText={( diff --git a/components/sidebar/sidebar_next_steps/sidebar_next_steps.tsx b/components/sidebar/sidebar_next_steps/sidebar_next_steps.tsx index 89d0517abe67..d1d46a45c450 100644 --- a/components/sidebar/sidebar_next_steps/sidebar_next_steps.tsx +++ b/components/sidebar/sidebar_next_steps/sidebar_next_steps.tsx @@ -11,6 +11,7 @@ import FormattedMarkdownMessage from 'components/formatted_markdown_message.jsx' import {Steps} from 'components/next_steps_view/steps'; import ProgressBar from 'components/progress_bar'; import {ModalIdentifiers, RecommendedNextSteps, Preferences} from 'utils/constants'; +import {localizeMessage} from 'utils/utils'; import './sidebar_next_steps.scss'; @@ -43,10 +44,15 @@ export default class SidebarNextSteps extends React.PureComponent } closeNextSteps = () => { + const screenTitle = this.props.showNextSteps ? + localizeMessage('sidebar_next_steps.gettingStarted', 'Getting Started') : + localizeMessage('sidebar_next_steps.tipsAndNextSteps', 'Tips & Next Steps'); + this.props.actions.openModal({ modalId: ModalIdentifiers.CLOSE_NEXT_STEPS_MODAL, dialogType: CloseNextStepsModal, dialogProps: { + screenTitle, onConfirm: this.onConfirmModal, onCancel: this.onCloseModal, } @@ -82,6 +88,40 @@ export default class SidebarNextSteps extends React.PureComponent const total = Steps.length; const complete = this.props.preferences.filter((pref) => pref.value).length; + let header = ( + + ); + if (!this.props.showNextSteps) { + header = ( + + ); + } + + let middleSection = ( + + ); + if (!this.props.showNextSteps) { + middleSection = ( + + ); + } + return (
>
- + {header}
- + {middleSection}
+ {this.props.showNextSteps &&
-
+
}
); } diff --git a/i18n/en.json b/i18n/en.json index dd4a05828e19..b9e11e92b219 100644 --- a/i18n/en.json +++ b/i18n/en.json @@ -2230,8 +2230,8 @@ "claim.oauth_to_email.switchTo": "Switch {type} to Email and Password", "claim.oauth_to_email.title": "Switch {type} Account to Email", "close_next_steps_modal.confirm": "Remove", - "close_next_steps_modal.header": "Remove Tip & Next Steps?", - "close_next_steps_modal.helpText": "Access Tips & Next Steps any time through the Help section in the Main Menu", + "close_next_steps_modal.header": "Remove {title}?", + "close_next_steps_modal.helpText": "Access {title} any time through the Main Menu", "close_next_steps_modal.mainText": "This will remove this section from your sidebar, but you can access it later in the Help section of the Main Menu.", "combined_system_message.added_to_channel.many_expanded": "{users} and {lastUser} were **added to the channel** by {actor}.", "combined_system_message.added_to_channel.one": "{firstUser} **added to the channel** by {actor}.", @@ -3403,7 +3403,9 @@ "sidebar_left.sidebar_channel_menu.unmuteChannel": "Unmute Channel", "sidebar_left.sidebar_channel_menu.unmuteConversation": "Unmute Conversation", "sidebar_next_steps.gettingStarted": "Getting Started", + "sidebar_next_steps.otherAreasToExplore": "A few other areas to explore", "sidebar_next_steps.stepsComplete": "{complete} / {total} steps complete", + "sidebar_next_steps.tipsAndNextSteps": "Tips & Next Steps", "sidebar_right_menu.console": "System Console", "sidebar_right_menu.flagged": "Saved Posts", "sidebar_right_menu.recentMentions": "Recent Mentions", From ccba981afeb9457301e8bc21af1a27adeda39ed0 Mon Sep 17 00:00:00 2001 From: Devin Binnie Date: Tue, 28 Jul 2020 09:17:16 -0400 Subject: [PATCH 6/8] Center the next steps modal --- .../sidebar/sidebar_next_steps/close_next_steps_modal.scss | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/components/sidebar/sidebar_next_steps/close_next_steps_modal.scss b/components/sidebar/sidebar_next_steps/close_next_steps_modal.scss index 7cddbdc29507..7cb6fd80347c 100644 --- a/components/sidebar/sidebar_next_steps/close_next_steps_modal.scss +++ b/components/sidebar/sidebar_next_steps/close_next_steps_modal.scss @@ -17,8 +17,9 @@ margin-top: 4px; } -.modal .CloseNextStepsModal { +.modal .GenericModal.modal-dialog.CloseNextStepsModal { max-width: 514px; + margin-top: calc(50vh - 133px); .GenericModal__header { text-align: center; From 69ece1b082a8d0538cdb7fd5909a801adb90db81 Mon Sep 17 00:00:00 2001 From: Devin Binnie Date: Tue, 28 Jul 2020 09:31:37 -0400 Subject: [PATCH 7/8] PR feedback --- ...odal.scss => remove_next_steps_modal.scss} | 8 ++++---- ..._modal.tsx => remove_next_steps_modal.tsx} | 20 +++++++++---------- .../sidebar_next_steps/sidebar_next_steps.tsx | 8 ++++---- i18n/en.json | 8 ++++---- utils/constants.jsx | 2 +- 5 files changed, 23 insertions(+), 23 deletions(-) rename components/sidebar/sidebar_next_steps/{close_next_steps_modal.scss => remove_next_steps_modal.scss} (88%) rename components/sidebar/sidebar_next_steps/{close_next_steps_modal.tsx => remove_next_steps_modal.tsx} (77%) diff --git a/components/sidebar/sidebar_next_steps/close_next_steps_modal.scss b/components/sidebar/sidebar_next_steps/remove_next_steps_modal.scss similarity index 88% rename from components/sidebar/sidebar_next_steps/close_next_steps_modal.scss rename to components/sidebar/sidebar_next_steps/remove_next_steps_modal.scss index 7cb6fd80347c..aa6aa4fd193e 100644 --- a/components/sidebar/sidebar_next_steps/close_next_steps_modal.scss +++ b/components/sidebar/sidebar_next_steps/remove_next_steps_modal.scss @@ -1,11 +1,11 @@ -.CloseNextStepsModal__helpBox { +.RemoveNextStepsModal__helpBox { position: fixed; top: 16px; left: 201px; z-index: 1050; } -.CloseNextStepsModal__helpText { +.RemoveNextStepsModal__helpText { font-weight: 600; font-size: 12px; line-height: 16px; @@ -17,7 +17,7 @@ margin-top: 4px; } -.modal .GenericModal.modal-dialog.CloseNextStepsModal { +.modal .GenericModal.modal-dialog.RemoveNextStepsModal { max-width: 514px; margin-top: calc(50vh - 133px); @@ -63,7 +63,7 @@ clip-path: polygon(0 0, 65px 0, 65px 63px, 305px 63px, 305px 0, 100% 0, 100% 100%, 0 100%); } - & ~ .CloseNextStepsModal__helpBox { + & ~ .RemoveNextStepsModal__helpBox { left: 266px; } } diff --git a/components/sidebar/sidebar_next_steps/close_next_steps_modal.tsx b/components/sidebar/sidebar_next_steps/remove_next_steps_modal.tsx similarity index 77% rename from components/sidebar/sidebar_next_steps/close_next_steps_modal.tsx rename to components/sidebar/sidebar_next_steps/remove_next_steps_modal.tsx index d857f1b30977..3e78620f55a2 100644 --- a/components/sidebar/sidebar_next_steps/close_next_steps_modal.tsx +++ b/components/sidebar/sidebar_next_steps/remove_next_steps_modal.tsx @@ -9,7 +9,7 @@ import FormattedMarkdownMessage from 'components/formatted_markdown_message.jsx' import GenericModal from 'components/generic_modal'; import closeNextStepsArrow from 'images/close_next_steps_arrow.svg'; -import './close_next_steps_modal.scss'; +import './remove_next_steps_modal.scss'; type Props = { screenTitle: string; @@ -17,20 +17,20 @@ type Props = { onCancel: () => void; } -export default function CloseNextStepsModal(props: Props) { +export default function RemoveNextStepsModal(props: Props) { const {onConfirm, onCancel, screenTitle} = props; return ( <> {ReactDOM.createPortal( -
+
- + )} > diff --git a/components/sidebar/sidebar_next_steps/sidebar_next_steps.tsx b/components/sidebar/sidebar_next_steps/sidebar_next_steps.tsx index d1d46a45c450..f7b8bb11f06f 100644 --- a/components/sidebar/sidebar_next_steps/sidebar_next_steps.tsx +++ b/components/sidebar/sidebar_next_steps/sidebar_next_steps.tsx @@ -15,7 +15,7 @@ import {localizeMessage} from 'utils/utils'; import './sidebar_next_steps.scss'; -import CloseNextStepsModal from './close_next_steps_modal'; +import RemoveNextStepsModal from './remove_next_steps_modal'; type Props = { active: boolean; @@ -49,8 +49,8 @@ export default class SidebarNextSteps extends React.PureComponent localizeMessage('sidebar_next_steps.tipsAndNextSteps', 'Tips & Next Steps'); this.props.actions.openModal({ - modalId: ModalIdentifiers.CLOSE_NEXT_STEPS_MODAL, - dialogType: CloseNextStepsModal, + modalId: ModalIdentifiers.REMOVE_NEXT_STEPS_MODAL, + dialogType: RemoveNextStepsModal, dialogProps: { screenTitle, onConfirm: this.onConfirmModal, @@ -60,7 +60,7 @@ export default class SidebarNextSteps extends React.PureComponent } onCloseModal = () => { - this.props.actions.closeModal(ModalIdentifiers.CLOSE_NEXT_STEPS_MODAL); + this.props.actions.closeModal(ModalIdentifiers.REMOVE_NEXT_STEPS_MODAL); } onConfirmModal = () => { diff --git a/i18n/en.json b/i18n/en.json index b9e11e92b219..8d4e1b1fcadd 100644 --- a/i18n/en.json +++ b/i18n/en.json @@ -2229,10 +2229,10 @@ "claim.oauth_to_email.pwdNotMatch": "Passwords do not match.", "claim.oauth_to_email.switchTo": "Switch {type} to Email and Password", "claim.oauth_to_email.title": "Switch {type} Account to Email", - "close_next_steps_modal.confirm": "Remove", - "close_next_steps_modal.header": "Remove {title}?", - "close_next_steps_modal.helpText": "Access {title} any time through the Main Menu", - "close_next_steps_modal.mainText": "This will remove this section from your sidebar, but you can access it later in the Help section of the Main Menu.", + "remove_next_steps_modal.confirm": "Remove", + "remove_next_steps_modal.header": "Remove {title}?", + "remove_next_steps_modal.helpText": "Access {title} any time through the Main Menu", + "remove_next_steps_modal.mainText": "This will remove this section from your sidebar, but you can access it later in the Help section of the Main Menu.", "combined_system_message.added_to_channel.many_expanded": "{users} and {lastUser} were **added to the channel** by {actor}.", "combined_system_message.added_to_channel.one": "{firstUser} **added to the channel** by {actor}.", "combined_system_message.added_to_channel.one_you": "You were **added to the channel** by {actor}.", diff --git a/utils/constants.jsx b/utils/constants.jsx index f27493ef1ba1..f0aff45439cc 100644 --- a/utils/constants.jsx +++ b/utils/constants.jsx @@ -262,7 +262,7 @@ export const ModalIdentifiers = { DELETE_CATEGORY: 'delete_category', SIDEBAR_WHATS_NEW_MODAL: 'sidebar_whats_new_modal', WARN_METRIC_ACK: 'warn_metric_acknowledgement', - CLOSE_NEXT_STEPS_MODAL: 'close_next_steps_modal', + REMOVE_NEXT_STEPS_MODAL: 'remove_next_steps_modal', }; export const UserStatuses = { From ddc579f23818ea8ae4674cefa208c2c172a8787b Mon Sep 17 00:00:00 2001 From: Devin Binnie Date: Tue, 28 Jul 2020 12:19:28 -0400 Subject: [PATCH 8/8] Translation fix --- i18n/en.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/i18n/en.json b/i18n/en.json index 8d4e1b1fcadd..3b4747824aaa 100644 --- a/i18n/en.json +++ b/i18n/en.json @@ -2229,10 +2229,6 @@ "claim.oauth_to_email.pwdNotMatch": "Passwords do not match.", "claim.oauth_to_email.switchTo": "Switch {type} to Email and Password", "claim.oauth_to_email.title": "Switch {type} Account to Email", - "remove_next_steps_modal.confirm": "Remove", - "remove_next_steps_modal.header": "Remove {title}?", - "remove_next_steps_modal.helpText": "Access {title} any time through the Main Menu", - "remove_next_steps_modal.mainText": "This will remove this section from your sidebar, but you can access it later in the Help section of the Main Menu.", "combined_system_message.added_to_channel.many_expanded": "{users} and {lastUser} were **added to the channel** by {actor}.", "combined_system_message.added_to_channel.one": "{firstUser} **added to the channel** by {actor}.", "combined_system_message.added_to_channel.one_you": "You were **added to the channel** by {actor}.", @@ -3229,6 +3225,10 @@ "remove_group_confirm_button": "Yes, Remove Group and {memberCount, plural, one {Member} other {Members}}", "remove_group_confirm_message": "{memberCount, number} {memberCount, plural, one {member} other {members}} associated to this group will be removed from the team. Are you sure you wish to remove this group and {memberCount} {memberCount, plural, one {member} other {members}}?", "remove_group_confirm_title": "Remove Group and {memberCount, number} {memberCount, plural, one {Member} other {Members}}", + "remove_next_steps_modal.confirm": "Remove", + "remove_next_steps_modal.header": "Remove {title}?", + "remove_next_steps_modal.helpText": "Access {title} any time through the Main Menu", + "remove_next_steps_modal.mainText": "This will remove this section from your sidebar, but you can access it later in the Help section of the Main Menu.", "removed_channel.channelName": "the channel", "removed_channel.from": "Removed from ", "removed_channel.okay": "Okay",