Skip to content
This repository has been archived by the owner on Mar 13, 2024. It is now read-only.

Commit

Permalink
[MM-26466] Close Next Steps Modal and functionality (#5995)
Browse files Browse the repository at this point in the history
* Hooked up the sidebar next steps bar and some fixes

* Integration of state into app for next steps view, close next steps view modal preliminary

* Styling and help arrow for modal

* Missed a translation

* PR feedback

* Center the next steps modal

* PR feedback

* Translation fix
  • Loading branch information
devinbinnie committed Jul 28, 2020
1 parent d461828 commit 77f56af
Show file tree
Hide file tree
Showing 22 changed files with 385 additions and 35 deletions.
11 changes: 11 additions & 0 deletions actions/views/next_steps.ts
Original file line number Diff line number Diff line change
@@ -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,
};
}
21 changes: 18 additions & 3 deletions components/channel_view/channel_view.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -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,
}),
};

Expand All @@ -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) {
Expand All @@ -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;
}
Expand All @@ -79,7 +85,6 @@ export default class ChannelView extends React.PureComponent {
url: props.match.url,
channelId: props.channelId,
deferredPostView: ChannelView.createDeferredPostView(),
showNextSteps: props.showNextSteps,
};
}

Expand All @@ -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');
Expand All @@ -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() {
Expand All @@ -126,7 +141,7 @@ export default class ChannelView extends React.PureComponent {
);
}

if (this.state.showNextSteps) {
if (this.props.showNextStepsEphemeral) {
return (
<NextStepsView/>
);
Expand Down
2 changes: 2 additions & 0 deletions components/channel_view/channel_view.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -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(),
},
};

Expand Down
3 changes: 3 additions & 0 deletions components/channel_view/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -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,
};
Expand All @@ -67,6 +69,7 @@ function mapStateToProps(state) {
function mapDispatchToProps(dispatch) {
return {
actions: bindActionCreators({
setShowNextStepsView,
goToLastViewedChannel,
}, dispatch),
};
Expand Down
3 changes: 2 additions & 1 deletion components/generic_modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {FormattedMessage} from 'react-intl';
import './generic_modal.scss';

type Props = {
className?: string;
onHide: () => void;
modalHeaderText: React.ReactNode;
show?: boolean;
Expand Down Expand Up @@ -109,7 +110,7 @@ export default class GenericModal extends React.PureComponent<Props, State> {

return (
<Modal
dialogClassName='a11y__modal GenericModal'
dialogClassName={classNames('a11y__modal GenericModal', this.props.className)}
show={this.state.show}
onHide={this.onHide}
onExited={this.onHide}
Expand Down
2 changes: 2 additions & 0 deletions components/next_steps_view/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';

Expand All @@ -33,6 +34,7 @@ function mapDispatchToProps(dispatch: Dispatch) {
return {
actions: bindActionCreators({
savePreferences,
setShowNextStepsView,
}, dispatch),
};
}
Expand Down
1 change: 1 addition & 0 deletions components/next_steps_view/next_steps_view.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ describe('components/next_steps_view', () => {
preferences: [],
skuName: '',
actions: {
setShowNextStepsView: jest.fn(),
savePreferences: jest.fn(),
},
};
Expand Down
1 change: 1 addition & 0 deletions components/next_steps_view/next_steps_view.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ type Props = {
skuName: string;
actions: {
savePreferences: (userId: string, preferences: PreferenceType[]) => void;
setShowNextStepsView: (show: boolean) => void;
};
};

Expand Down
6 changes: 5 additions & 1 deletion components/next_steps_view/steps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';

Expand Down Expand Up @@ -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);
}
Expand Down
8 changes: 4 additions & 4 deletions components/sidebar/__snapshots__/sidebar.test.tsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ exports[`components/sidebar should match snapshot 1`] = `
onDragStart={[Function]}
/>
<Connect(DataPrefetch) />
<SidebarNextSteps />
<Connect(SidebarNextSteps) />
<Connect(NewChannelFlow)
canCreatePrivateChannel={true}
canCreatePublicChannel={true}
Expand Down Expand Up @@ -77,7 +77,7 @@ exports[`components/sidebar should match snapshot when direct channels modal is
onDragStart={[Function]}
/>
<Connect(DataPrefetch) />
<SidebarNextSteps />
<Connect(SidebarNextSteps) />
<Connect(NewChannelFlow)
canCreatePrivateChannel={true}
canCreatePublicChannel={true}
Expand Down Expand Up @@ -124,7 +124,7 @@ exports[`components/sidebar should match snapshot when isDataPrefechEnabled is d
onDragEnd={[Function]}
onDragStart={[Function]}
/>
<SidebarNextSteps />
<Connect(SidebarNextSteps) />
<Connect(NewChannelFlow)
canCreatePrivateChannel={true}
canCreatePublicChannel={true}
Expand Down Expand Up @@ -168,7 +168,7 @@ exports[`components/sidebar should match snapshot when more channels modal is op
onDragStart={[Function]}
/>
<Connect(DataPrefetch) />
<SidebarNextSteps />
<Connect(SidebarNextSteps) />
<Connect(NewChannelFlow)
canCreatePrivateChannel={true}
canCreatePublicChannel={true}
Expand Down
2 changes: 1 addition & 1 deletion components/sidebar/sidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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 = {
Expand Down
41 changes: 41 additions & 0 deletions components/sidebar/sidebar_next_steps/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// 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';

import SidebarNextSteps from './sidebar_next_steps';

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),
});
}

function mapDispatchToProps(dispatch: Dispatch) {
return {
actions: bindActionCreators({
savePreferences,
openModal,
closeModal,
setShowNextStepsView,
}, dispatch),
};
}

export default connect(makeMapStateToProps, mapDispatchToProps)(SidebarNextSteps);
69 changes: 69 additions & 0 deletions components/sidebar/sidebar_next_steps/remove_next_steps_modal.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
.RemoveNextStepsModal__helpBox {
position: fixed;
top: 16px;
left: 201px;
z-index: 1050;
}

.RemoveNextStepsModal__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;
}

.modal .GenericModal.modal-dialog.RemoveNextStepsModal {
max-width: 514px;
margin-top: calc(50vh - 133px);

.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-content {
padding: 40px 36px 24px 36px;
}

.GenericModal__button {
padding: 13px 20px;
line-height: 14px;

& +.GenericModal__button {
margin-left: 10px;
}
}
}

.modal-backdrop.in {
clip-path: polygon(0 0, 0 63px, 240px 63px, 240px 0, 100% 0, 100% 100%, 0 100%);
}

.multi-teams {
& ~ div .modal-backdrop.in {
clip-path: polygon(0 0, 65px 0, 65px 63px, 305px 63px, 305px 0, 100% 0, 100% 100%, 0 100%);
}

& ~ .RemoveNextStepsModal__helpBox {
left: 266px;
}
}
Loading

0 comments on commit 77f56af

Please sign in to comment.