PLT-4257 Add pop-up asking if user wants to reset status (#6526)

* Add pop-up asking if user wants to reset status

* Update test snapshot

* Update prop name for old uses of confirm modal

* Updating checkbox (#6586)

* Updating style for checkbox (#6596)
Этот коммит содержится в:
Joram Wilander
2017-06-06 17:24:08 -04:00
коммит произвёл GitHub
родитель 02f09b8af9
Коммит 6e7b912ec6
20 изменённых файлов: 419 добавлений и 50 удалений

Просмотреть файл

@@ -202,7 +202,7 @@ export default class SystemUsersDropdown extends React.Component {
title={title}
message={message}
confirmButtonClass={confirmButtonClass}
confirmButton={deactivateMemberButton}
confirmButtonText={deactivateMemberButton}
onConfirm={this.handleDeactivateMember}
onCancel={this.handleDeactivateCancel}
/>
@@ -467,7 +467,7 @@ export default class SystemUsersDropdown extends React.Component {
show={this.state.showDemoteModal}
title={title}
message={message}
confirmButton={confirmButton}
confirmButtonText={confirmButton}
onConfirm={this.handleDemoteSubmit}
onCancel={this.handleDemoteCancel}
/>

Просмотреть файл

@@ -272,7 +272,7 @@ export default class ChannelHeader extends React.Component {
title={title}
message={message}
confirmButtonClass={buttonClass}
confirmButton={button}
confirmButtonText={button}
onConfirm={() => ChannelActions.leaveChannel(this.state.channel.id)}
onCancel={this.hideLeaveChannelModal}
/>

Просмотреть файл

@@ -1,18 +1,70 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
import {FormattedMessage} from 'react-intl';
import {Modal} from 'react-bootstrap';
import PropTypes from 'prop-types';
import React from 'react';
import {Modal} from 'react-bootstrap';
import PropTypes from 'prop-types';
import {FormattedMessage} from 'react-intl';
export default class ConfirmModal extends React.Component {
constructor(props) {
super(props);
static propTypes = {
this.handleKeypress = this.handleKeypress.bind(this);
/*
* Set to show modal
*/
show: PropTypes.bool.isRequired,
/*
* Title to use for the modal
*/
title: PropTypes.node,
/*
* Message to display in the body of the modal
*/
message: PropTypes.node,
/*
* The CSS class to apply to the confirm button
*/
confirmButtonClass: PropTypes.string,
/*
* Text/jsx element on the confirm button
*/
confirmButtonText: PropTypes.node,
/*
* Text/jsx element on the cancel button
*/
cancelButtonText: PropTypes.node,
/*
* Set to show checkbox
*/
showCheckbox: PropTypes.bool,
/*
* Text/jsx element to display with the checkbox
*/
checkboxText: PropTypes.node,
/*
* Function called when the confirm button or ENTER is pressed. Passes `true` if the checkbox is checked
*/
onConfirm: PropTypes.func.isRequired,
/*
* Function called when the cancel button is pressed or the modal is hidden. Passes `true` if the checkbox is checked
*/
onCancel: PropTypes.func.isRequired
}
static defaultProps = {
title: '',
message: '',
confirmButtonClass: 'btn btn-primary',
confirmButtonText: ''
}
componentDidMount() {
@@ -33,13 +85,50 @@ export default class ConfirmModal extends React.Component {
}
}
handleKeypress(e) {
handleKeypress = (e) => {
if (e.key === 'Enter' && this.props.show) {
this.props.onConfirm(e);
this.handleConfirm();
}
}
handleConfirm = () => {
const checked = this.refs.checkbox ? this.refs.checkbox.checked : false;
this.props.onConfirm(checked);
}
handleCancel = () => {
const checked = this.refs.checkbox ? this.refs.checkbox.checked : false;
this.props.onCancel(checked);
}
render() {
let checkbox;
if (this.props.showCheckbox) {
checkbox = (
<div className='checkbox text-right margin-bottom--none'>
<label>
<input
ref='checkbox'
type='checkbox'
/>
{this.props.checkboxText}
</label>
</div>
);
}
let cancelText;
if (this.props.cancelButtonText) {
cancelText = this.props.cancelButtonText;
} else {
cancelText = (
<FormattedMessage
id='confirm_modal.cancel'
defaultMessage='Cancel'
/>
);
}
return (
<Modal
className='modal-confirm'
@@ -51,43 +140,25 @@ export default class ConfirmModal extends React.Component {
</Modal.Header>
<Modal.Body>
{this.props.message}
{checkbox}
</Modal.Body>
<Modal.Footer>
<button
type='button'
className='btn btn-default'
onClick={this.props.onCancel}
onClick={this.handleCancel}
>
<FormattedMessage
id='confirm_modal.cancel'
defaultMessage='Cancel'
/>
{cancelText}
</button>
<button
type='button'
className={this.props.confirmButtonClass}
onClick={this.props.onConfirm}
onClick={this.handleConfirm}
>
{this.props.confirmButton}
{this.props.confirmButtonText}
</button>
</Modal.Footer>
</Modal>
);
}
}
ConfirmModal.defaultProps = {
title: '',
message: '',
confirmButtonClass: 'btn btn-primary',
confirmButton: ''
};
ConfirmModal.propTypes = {
show: PropTypes.bool.isRequired,
title: PropTypes.node,
message: PropTypes.node,
confirmButtonClass: PropTypes.string,
confirmButton: PropTypes.node,
onConfirm: PropTypes.func.isRequired,
onCancel: PropTypes.func.isRequired
};

Просмотреть файл

@@ -120,7 +120,9 @@ export default class CreatePost extends React.Component {
}
doSubmit(e) {
e.preventDefault();
if (e) {
e.preventDefault();
}
const post = {};
post.file_ids = [];

Просмотреть файл

@@ -28,8 +28,8 @@ export default class DeleteModalTrigger extends React.Component {
});
}
handleConfirm(e) {
this.props.onDelete(e);
handleConfirm() {
this.props.onDelete();
}
handleCancel() {
@@ -57,7 +57,7 @@ export default class DeleteModalTrigger extends React.Component {
show={this.state.showDeleteModal}
title={this.modalTitle}
message={this.modalMessage}
confirmButton={this.modalConfirmButton}
confirmButtonText={this.modalConfirmButton}
onConfirm={this.handleConfirm}
onCancel={this.handleCancel}
onKeyDown={this.handleKeyDown}

Просмотреть файл

@@ -719,7 +719,7 @@ export default class EditCommand extends React.Component {
<ConfirmModal
title={confirmTitle}
message={confirmMessage}
confirmButton={confirmButton}
confirmButtonText={confirmButton}
show={this.state.showConfirmModal}
onConfirm={this.handleUpdate}
onCancel={this.confirmModalDismissed}

Просмотреть файл

@@ -180,7 +180,7 @@ export default class EditOutgoingWebhook extends AbstractOutgoingWebhook {
<ConfirmModal
title={confirmTitle}
message={confirmMessage}
confirmButton={confirmButton}
confirmButtonText={confirmButton}
show={this.state.showConfirmModal}
onConfirm={this.handleUpdate}
onCancel={this.confirmModalDismissed}

Просмотреть файл

@@ -517,7 +517,7 @@ class InviteMemberModal extends React.Component {
<ConfirmModal
title={formatMessage(holders.modalTitle)}
message={formatMessage(holders.modalMessage)}
confirmButton={formatMessage(holders.modalButton)}
confirmButtonText={formatMessage(holders.modalButton)}
show={this.state.showConfirmModal}
onConfirm={this.handleHide.bind(this, false)}
onCancel={() => this.setState({showConfirmModal: false})}

Просмотреть файл

@@ -753,7 +753,7 @@ export default class Navbar extends React.Component {
title={title}
message={message}
confirmButtonClass={buttonClass}
confirmButton={button}
confirmButtonText={button}
onConfirm={() => ChannelActions.leaveChannel(this.state.channel.id)}
onCancel={this.hideLeaveChannelModal}
/>

Просмотреть файл

@@ -1,9 +1,8 @@
import PropTypes from 'prop-types';
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
import React from 'react';
import PropTypes from 'prop-types';
import $ from 'jquery';
@@ -42,6 +41,7 @@ import RemovedFromChannelModal from 'components/removed_from_channel_modal.jsx';
import ImportThemeModal from 'components/user_settings/import_theme_modal.jsx';
import InviteMemberModal from 'components/invite_member_modal.jsx';
import LeaveTeamModal from 'components/leave_team_modal.jsx';
import ResetStatusModal from 'components/reset_status_modal';
import iNoBounce from 'inobounce';
import * as UserAgent from 'utils/user_agent.jsx';
@@ -229,6 +229,7 @@ export default class NeedsTeam extends React.Component {
<EditPostModal/>
<DeletePostModal/>
<RemovedFromChannelModal/>
<ResetStatusModal/>
</div>
</div>
);

Просмотреть файл

@@ -0,0 +1,34 @@
// Copyright (c) 2017 Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
import {connect} from 'react-redux';
import {bindActionCreators} from 'redux';
import {Preferences} from 'mattermost-redux/constants';
import {get} from 'mattermost-redux/selectors/entities/preferences';
import {savePreferences} from 'mattermost-redux/actions/preferences';
import {setStatus} from 'mattermost-redux/actions/users';
import {autoResetStatus} from 'actions/user_actions.jsx';
import ResetStatusModal from './reset_status_modal.jsx';
function mapStateToProps(state, ownProps) {
const {currentUserId} = state.entities.users;
return {
...ownProps,
autoResetPref: get(state, Preferences.CATEGORY_AUTO_RESET_MANUAL_STATUS, currentUserId, '')
};
}
function mapDispatchToProps(dispatch) {
return {
actions: bindActionCreators({
autoResetStatus,
setStatus,
savePreferences
}, dispatch)
};
}
export default connect(mapStateToProps, mapDispatchToProps)(ResetStatusModal);

Просмотреть файл

@@ -0,0 +1,142 @@
// Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
import ConfirmModal from 'components/confirm_modal.jsx';
import {toTitleCase} from 'utils/utils.jsx';
import React from 'react';
import PropTypes from 'prop-types';
import {FormattedMessage} from 'react-intl';
import {Preferences} from 'mattermost-redux/constants';
export default class ResetStatusModal extends React.PureComponent {
static propTypes = {
/*
* The user's preference for whether their status is automatically reset
*/
autoResetPref: PropTypes.string,
actions: PropTypes.shape({
/*
* Function to get and then reset the user's status if needed
*/
autoResetStatus: PropTypes.func.isRequired,
/*
* Function to set the status for a user
*/
setStatus: PropTypes.func.isRequired,
/*
* Function to save user preferences
*/
savePreferences: PropTypes.func.isRequired
}).isRequired
}
constructor(props) {
super(props);
this.state = {
show: false,
currentUserStatus: {}
};
}
componentDidMount() {
this.props.actions.autoResetStatus().then(
(status) => {
const statusIsManual = status.manual;
const autoResetPrefNotSet = this.props.autoResetPref === '';
this.setState({
currentUserStatus: status, // Set in state until status refactor where we store 'manual' field in redux
show: Boolean(statusIsManual && autoResetPrefNotSet)
});
}
);
}
onConfirm = (checked) => {
this.setState({show: false});
const newStatus = {...this.state.currentUserStatus};
newStatus.status = 'online';
this.props.actions.setStatus(newStatus);
if (checked) {
const pref = {category: Preferences.CATEGORY_AUTO_RESET_MANUAL_STATUS, user_id: newStatus.user_id, name: newStatus.user_id, value: 'true'};
this.props.actions.savePreferences(pref.user_id, [pref]);
}
}
onCancel = (checked) => {
this.setState({show: false});
if (checked) {
const status = {...this.state.currentUserStatus};
const pref = {category: Preferences.CATEGORY_AUTO_RESET_MANUAL_STATUS, user_id: status.user_id, name: status.user_id, value: 'false'};
this.props.actions.savePreferences(pref.user_id, [pref]);
}
}
render() {
const userStatus = toTitleCase(this.state.currentUserStatus.status || '');
const manualStatusTitle = (
<FormattedMessage
id='modal.manual_status.title'
defaultMessage='Your status is set to "{status}"'
values={{
status: userStatus
}}
/>
);
const manualStatusMessage = (
<FormattedMessage
id='modal.manual_status.message'
defaultMessage='Would you like to switch your status to "Online"?'
/>
);
const manualStatusButton = (
<FormattedMessage
id='modal.manual_status.button'
defaultMessage='Yes, set my status to "Online"'
/>
);
const manualStatusCancel = (
<FormattedMessage
id='modal.manual_status.cancel'
defaultMessage='No, keep it as "{status}"'
values={{
status: userStatus
}}
/>
);
const manualStatusCheckbox = (
<FormattedMessage
id='modal.manual_status.ask'
defaultMessage='Do not ask me again'
/>
);
return (
<ConfirmModal
show={this.state.show}
title={manualStatusTitle}
message={manualStatusMessage}
confirmButtonText={manualStatusButton}
onConfirm={this.onConfirm}
cancelButtonText={manualStatusCancel}
onCancel={this.onCancel}
showCheckbox={true}
checkboxText={manualStatusCheckbox}
/>
);
}
}

Просмотреть файл

@@ -357,7 +357,7 @@ export default class TeamMembersDropdown extends React.Component {
show={this.state.showDemoteModal}
title={title}
message={message}
confirmButton={confirmButton}
confirmButtonText={confirmButton}
onConfirm={this.handleDemoteSubmit}
onCancel={this.handleDemoteCancel}
/>

Просмотреть файл

@@ -269,7 +269,7 @@ class UserSettingsModal extends React.Component {
<ConfirmModal
title={formatMessage(holders.confirmTitle)}
message={formatMessage(holders.confirmMsg)}
confirmButton={formatMessage(holders.confirmBtns)}
confirmButtonText={formatMessage(holders.confirmBtns)}
show={this.state.showConfirmModal}
onConfirm={this.handleConfirm}
onCancel={this.handleCancelConfirmation}