From 6c4c706313eb765eb00c639f381646be74f27b69 Mon Sep 17 00:00:00 2001 From: Joram Wilander Date: Tue, 25 Apr 2017 11:46:02 -0400 Subject: Start moving webapp to Redux (#6140) * Start moving webapp to Redux * Fix localforage import * Updates per feedback * Feedback udpates and a few fixes * Minor updates * Fix statuses, config not loading properly, getMe sanitizing too much * Fix preferences * Fix user autocomplete * Fix sessions and audits * Fix error handling for all redux actions * Use new directory structure for components and containers * Refresh immediately on logout instead of after timeout * Add fetch polyfill --- .../user_settings/user_settings_general.jsx | 1207 -------------------- 1 file changed, 1207 deletions(-) delete mode 100644 webapp/components/user_settings/user_settings_general.jsx (limited to 'webapp/components/user_settings/user_settings_general.jsx') diff --git a/webapp/components/user_settings/user_settings_general.jsx b/webapp/components/user_settings/user_settings_general.jsx deleted file mode 100644 index ce4349519..000000000 --- a/webapp/components/user_settings/user_settings_general.jsx +++ /dev/null @@ -1,1207 +0,0 @@ -// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. -// See License.txt for license information. - -import $ from 'jquery'; -import SettingItemMin from '../setting_item_min.jsx'; -import SettingItemMax from '../setting_item_max.jsx'; -import SettingPicture from '../setting_picture.jsx'; - -import UserStore from 'stores/user_store.jsx'; -import ErrorStore from 'stores/error_store.jsx'; - -import Client from 'client/web_client.jsx'; -import Constants from 'utils/constants.jsx'; -import * as AsyncClient from 'utils/async_client.jsx'; -import * as Utils from 'utils/utils.jsx'; - -import {intlShape, injectIntl, defineMessages, FormattedMessage, FormattedHTMLMessage, FormattedDate} from 'react-intl'; -import {updateUser, uploadProfileImage} from 'actions/user_actions.jsx'; -import {trackEvent} from 'actions/diagnostics_actions.jsx'; - -const holders = defineMessages({ - usernameReserved: { - id: 'user.settings.general.usernameReserved', - defaultMessage: 'This username is reserved, please choose a new one.' - }, - usernameRestrictions: { - id: 'user.settings.general.usernameRestrictions', - defaultMessage: "Username must begin with a letter, and contain between {min} to {max} lowercase characters made up of numbers, letters, and the symbols '.', '-', and '_'." - }, - validEmail: { - id: 'user.settings.general.validEmail', - defaultMessage: 'Please enter a valid email address.' - }, - emailMatch: { - id: 'user.settings.general.emailMatch', - defaultMessage: 'The new emails you entered do not match.' - }, - checkEmail: { - id: 'user.settings.general.checkEmail', - defaultMessage: 'Check your email at {email} to verify the address.' - }, - validImage: { - id: 'user.settings.general.validImage', - defaultMessage: 'Only JPG or PNG images may be used for profile pictures' - }, - imageTooLarge: { - id: 'user.settings.general.imageTooLarge', - defaultMessage: 'Unable to upload profile image. File is too large.' - }, - uploadImage: { - id: 'user.settings.general.uploadImage', - defaultMessage: "Click 'Edit' to upload an image." - }, - fullName: { - id: 'user.settings.general.fullName', - defaultMessage: 'Full Name' - }, - nickname: { - id: 'user.settings.general.nickname', - defaultMessage: 'Nickname' - }, - username: { - id: 'user.settings.general.username', - defaultMessage: 'Username' - }, - profilePicture: { - id: 'user.settings.general.profilePicture', - defaultMessage: 'Profile Picture' - }, - close: { - id: 'user.settings.general.close', - defaultMessage: 'Close' - }, - position: { - id: 'user.settings.general.position', - defaultMessage: 'Position' - } -}); - -import React from 'react'; - -class UserSettingsGeneralTab extends React.Component { - constructor(props) { - super(props); - this.submitActive = false; - - this.submitUsername = this.submitUsername.bind(this); - this.submitNickname = this.submitNickname.bind(this); - this.submitName = this.submitName.bind(this); - this.submitEmail = this.submitEmail.bind(this); - this.submitUser = this.submitUser.bind(this); - this.submitPicture = this.submitPicture.bind(this); - this.submitPosition = this.submitPosition.bind(this); - - this.updateUsername = this.updateUsername.bind(this); - this.updateFirstName = this.updateFirstName.bind(this); - this.updateLastName = this.updateLastName.bind(this); - this.updateNickname = this.updateNickname.bind(this); - this.updateEmail = this.updateEmail.bind(this); - this.updateConfirmEmail = this.updateConfirmEmail.bind(this); - this.updatePicture = this.updatePicture.bind(this); - this.updateSection = this.updateSection.bind(this); - this.updatePosition = this.updatePosition.bind(this); - this.updatedCroppedPicture = this.updatedCroppedPicture.bind(this); - - this.state = this.setupInitialState(props); - } - - submitUsername(e) { - e.preventDefault(); - - const user = Object.assign({}, this.props.user); - const username = this.state.username.trim().toLowerCase(); - - const {formatMessage} = this.props.intl; - const usernameError = Utils.isValidUsername(username); - if (usernameError === 'Cannot use a reserved word as a username.') { - this.setState({clientError: formatMessage(holders.usernameReserved)}); - return; - } else if (usernameError) { - this.setState({clientError: formatMessage(holders.usernameRestrictions, {min: Constants.MIN_USERNAME_LENGTH, max: Constants.MAX_USERNAME_LENGTH})}); - return; - } - - if (user.username === username) { - this.updateSection(''); - return; - } - - user.username = username; - - trackEvent('settings', 'user_settings_update', {field: 'username'}); - - this.submitUser(user, Constants.UserUpdateEvents.USERNAME, false); - } - - submitNickname(e) { - e.preventDefault(); - - const user = Object.assign({}, this.props.user); - const nickname = this.state.nickname.trim(); - - if (user.nickname === nickname) { - this.updateSection(''); - return; - } - - user.nickname = nickname; - - trackEvent('settings', 'user_settings_update', {field: 'username'}); - - this.submitUser(user, Constants.UserUpdateEvents.NICKNAME, false); - } - - submitName(e) { - e.preventDefault(); - - const user = Object.assign({}, this.props.user); - const firstName = this.state.firstName.trim(); - const lastName = this.state.lastName.trim(); - - if (user.first_name === firstName && user.last_name === lastName) { - this.updateSection(''); - return; - } - - user.first_name = firstName; - user.last_name = lastName; - - trackEvent('settings', 'user_settings_update', {field: 'fullname'}); - - this.submitUser(user, Constants.UserUpdateEvents.FULLNAME, false); - } - - submitEmail(e) { - e.preventDefault(); - - const user = Object.assign({}, this.props.user); - const email = this.state.email.trim().toLowerCase(); - const confirmEmail = this.state.confirmEmail.trim().toLowerCase(); - - const {formatMessage} = this.props.intl; - - if (email === user.email && (confirmEmail === '' || confirmEmail === user.email)) { - this.updateSection(''); - return; - } - - if (email === '' || !Utils.isEmail(email)) { - this.setState({emailError: formatMessage(holders.validEmail), clientError: '', serverError: ''}); - return; - } - - if (email !== confirmEmail) { - this.setState({emailError: formatMessage(holders.emailMatch), clientError: '', serverError: ''}); - return; - } - - user.email = email; - trackEvent('settings', 'user_settings_update', {field: 'email'}); - this.submitUser(user, Constants.UserUpdateEvents.EMAIL, true); - } - - submitUser(user, type, emailUpdated) { - updateUser(user, type, - () => { - this.updateSection(''); - AsyncClient.getMe(); - const verificationEnabled = global.window.mm_config.SendEmailNotifications === 'true' && global.window.mm_config.RequireEmailVerification === 'true' && emailUpdated; - - if (verificationEnabled) { - ErrorStore.storeLastError({message: this.props.intl.formatMessage(holders.checkEmail, {email: user.email})}); - ErrorStore.emitChange(); - this.setState({emailChangeInProgress: true}); - } - }, - (err) => { - let serverError; - if (err.message) { - serverError = err.message; - } else { - serverError = err; - } - this.setState({serverError, emailError: '', clientError: ''}); - } - ); - } - - submitPicture(e) { - e.preventDefault(); - - if (!this.state.picture) { - return; - } - - if (!this.submitActive) { - return; - } - - trackEvent('settings', 'user_settings_update', {field: 'picture'}); - - const {formatMessage} = this.props.intl; - const picture = this.state.picture; - - if (picture.type !== 'image/jpeg' && picture.type !== 'image/png') { - this.setState({clientError: formatMessage(holders.validImage)}); - return; - } else if (picture.size > this.state.maxFileSize) { - this.setState({clientError: formatMessage(holders.imageTooLarge)}); - return; - } - - this.setState({loadingPicture: true}); - - uploadProfileImage( - picture, - () => { - this.updateSection(''); - this.submitActive = false; - }, - (err) => { - var state = this.setupInitialState(this.props); - state.serverError = err.message; - this.setState(state); - } - ); - } - - submitPosition(e) { - e.preventDefault(); - - const user = Object.assign({}, this.props.user); - const position = this.state.position.trim(); - - if (user.position === position) { - this.updateSection(''); - return; - } - - user.position = position; - - trackEvent('settings', 'user_settings_update', {field: 'position'}); - - this.submitUser(user, Constants.UserUpdateEvents.Position, false); - } - - updateUsername(e) { - this.setState({username: e.target.value}); - } - - updateFirstName(e) { - this.setState({firstName: e.target.value}); - } - - updateLastName(e) { - this.setState({lastName: e.target.value}); - } - - updateNickname(e) { - this.setState({nickname: e.target.value}); - } - - updatePosition(e) { - this.setState({position: e.target.value}); - } - - updateEmail(e) { - this.setState({email: e.target.value}); - } - - updateConfirmEmail(e) { - this.setState({confirmEmail: e.target.value}); - } - - updatedCroppedPicture(file) { - if (file) { - this.setState({picture: file}); - - this.submitActive = true; - this.setState({clientError: null}); - } else { - this.setState({picture: null}); - } - } - - updatePicture(e) { - if (e.target.files && e.target.files[0]) { - this.setState({picture: e.target.files[0]}); - - this.submitActive = true; - this.setState({clientError: null}); - } else { - this.setState({picture: null}); - } - } - - updateSection(section) { - if ($('.section-max').length) { - $('.settings-modal .modal-body').scrollTop(0).perfectScrollbar('update'); - } - const emailChangeInProgress = this.state.emailChangeInProgress; - this.setState(Object.assign({}, this.setupInitialState(this.props), {emailChangeInProgress, clientError: '', serverError: '', emailError: ''})); - this.submitActive = false; - this.props.updateSection(section); - } - - setupInitialState(props) { - const user = props.user; - - return { - username: user.username, - firstName: user.first_name, - lastName: user.last_name, - nickname: user.nickname, - position: user.position, - email: user.email, - confirmEmail: '', - picture: null, - loadingPicture: false, - emailChangeInProgress: false, - maxFileSize: global.window.mm_config.MaxFileSize - }; - } - - createEmailSection() { - let emailSection; - - if (this.props.activeSection === 'email') { - const emailEnabled = global.window.mm_config.SendEmailNotifications === 'true'; - const emailVerificationEnabled = global.window.mm_config.RequireEmailVerification === 'true'; - const inputs = []; - - let helpText = ( - - ); - - if (!emailEnabled) { - helpText = ( -
- -
- ); - } else if (!emailVerificationEnabled) { - helpText = ( - - ); - } else if (this.state.emailChangeInProgress) { - const newEmail = UserStore.getCurrentUser().email; - if (newEmail) { - helpText = ( - - ); - } - } - - let submit = null; - - if (this.props.user.auth_service === '') { - inputs.push( -
-
- -
- -
-
-
- ); - - inputs.push( -
-
- -
- -
-
- {helpText} -
- ); - - submit = this.submitEmail; - } else if (this.props.user.auth_service === Constants.GITLAB_SERVICE) { - inputs.push( -
-
- -
- {helpText} -
- ); - } else if (this.props.user.auth_service === Constants.GOOGLE_SERVICE) { - inputs.push( -
-
- -
- {helpText} -
- ); - } else if (this.props.user.auth_service === Constants.OFFICE365_SERVICE) { - inputs.push( -
-
- -
- {helpText} -
- ); - } else if (this.props.user.auth_service === Constants.LDAP_SERVICE) { - inputs.push( -
-
- -
-
- ); - } else if (this.props.user.auth_service === Constants.SAML_SERVICE) { - inputs.push( -
-
- -
- {helpText} -
- ); - } - - emailSection = ( - - } - inputs={inputs} - submit={submit} - server_error={this.state.serverError} - client_error={this.state.emailError} - updateSection={(e) => { - this.updateSection(''); - e.preventDefault(); - }} - /> - ); - } else { - let describe = ''; - if (this.props.user.auth_service === '') { - if (this.state.emailChangeInProgress) { - const newEmail = UserStore.getCurrentUser().email; - if (newEmail) { - describe = ( - - ); - } else { - describe = ( - - ); - } - } else { - describe = UserStore.getCurrentUser().email; - } - } else if (this.props.user.auth_service === Constants.GITLAB_SERVICE) { - describe = ( - - ); - } else if (this.props.user.auth_service === Constants.GOOGLE_SERVICE) { - describe = ( - - ); - } else if (this.props.user.auth_service === Constants.OFFICE365_SERVICE) { - describe = ( - - ); - } else if (this.props.user.auth_service === Constants.LDAP_SERVICE) { - describe = ( - - ); - } else if (this.props.user.auth_service === Constants.SAML_SERVICE) { - describe = ( - - ); - } - - emailSection = ( - - } - describe={describe} - updateSection={() => { - this.updateSection('email'); - }} - /> - ); - } - - return emailSection; - } - - render() { - const user = this.props.user; - const {formatMessage} = this.props.intl; - - let clientError = null; - if (this.state.clientError) { - clientError = this.state.clientError; - } - let serverError = null; - if (this.state.serverError) { - serverError = this.state.serverError; - } - - let nameSection; - const inputs = []; - - if (this.props.activeSection === 'name') { - let extraInfo; - let submit = null; - if (this.props.user.auth_service === '' || - ((this.props.user.auth_service === 'ldap' || this.props.user.auth_service === Constants.SAML_SERVICE) && - (global.window.mm_config.FirstNameAttributeSet === 'false' || global.window.mm_config.LastNameAttributeSet === 'false'))) { - inputs.push( -
- -
- -
-
- ); - - inputs.push( -
- -
- -
-
- ); - - function notifClick(e) { - e.preventDefault(); - this.updateSection(''); - this.props.updateTab('notifications'); - } - - const notifLink = ( - - - - ); - - extraInfo = ( - - - - ); - - submit = this.submitName; - } else { - extraInfo = ( - - - - ); - } - - nameSection = ( - { - this.updateSection(''); - e.preventDefault(); - }} - extraInfo={extraInfo} - /> - ); - } else { - let describe = ''; - - if (user.first_name && user.last_name) { - describe = user.first_name + ' ' + user.last_name; - } else if (user.first_name) { - describe = user.first_name; - } else if (user.last_name) { - describe = user.last_name; - } else { - describe = ( - - ); - } - - nameSection = ( - { - this.updateSection('name'); - }} - /> - ); - } - - let nicknameSection; - if (this.props.activeSection === 'nickname') { - let extraInfo; - let submit = null; - if ((this.props.user.auth_service === 'ldap' || this.props.user.auth_service === Constants.SAML_SERVICE) && global.window.mm_config.NicknameAttributeSet === 'true') { - extraInfo = ( - - - - ); - } else { - let nicknameLabel = ( - - ); - if (Utils.isMobile()) { - nicknameLabel = ''; - } - - inputs.push( -
- -
- -
-
- ); - - extraInfo = ( - - - - ); - - submit = this.submitNickname; - } - - nicknameSection = ( - { - this.updateSection(''); - e.preventDefault(); - }} - extraInfo={extraInfo} - /> - ); - } else { - let describe = ''; - if (user.nickname) { - describe = user.nickname; - } else { - describe = ( - - ); - } - - nicknameSection = ( - { - this.updateSection('nickname'); - }} - /> - ); - } - - let usernameSection; - if (this.props.activeSection === 'username') { - let extraInfo; - let submit = null; - if (this.props.user.auth_service === '') { - let usernameLabel = ( - - ); - if (Utils.isMobile()) { - usernameLabel = ''; - } - - inputs.push( -
- -
- -
-
- ); - - extraInfo = ( - - - - ); - - submit = this.submitUsername; - } else { - extraInfo = ( - - - - ); - } - - usernameSection = ( - { - this.updateSection(''); - e.preventDefault(); - }} - extraInfo={extraInfo} - /> - ); - } else { - usernameSection = ( - { - this.updateSection('username'); - }} - /> - ); - } - - let positionSection; - if (this.props.activeSection === 'position') { - let extraInfo; - let submit = null; - if ((this.props.user.auth_service === 'ldap' || this.props.user.auth_service === Constants.SAML_SERVICE) && global.window.mm_config.PositionAttributeSet === 'true') { - extraInfo = ( - - - - ); - } else { - let positionLabel = ( - - ); - if (Utils.isMobile()) { - positionLabel = ''; - } - - inputs.push( -
- -
- -
-
- ); - - extraInfo = ( - - - - ); - - submit = this.submitPosition; - } - - positionSection = ( - { - this.updateSection(''); - e.preventDefault(); - }} - extraInfo={extraInfo} - /> - ); - } else { - let describe = ''; - if (user.position) { - describe = user.position; - } else { - describe = ( - - ); - } - - positionSection = ( - { - this.updateSection('position'); - }} - /> - ); - } - - const emailSection = this.createEmailSection(); - - let pictureSection; - if (this.props.activeSection === 'picture') { - pictureSection = ( - - ); - } else { - let minMessage = formatMessage(holders.uploadImage); - if (user.last_picture_update) { - minMessage = ( - - ) - }} - /> - ); - } - pictureSection = ( - { - this.updateSection('picture'); - }} - /> - ); - } - - return ( -
-
- -

-
- -
- -

-
-
-

- -

-
- {nameSection} -
- {usernameSection} -
- {nicknameSection} -
- {positionSection} -
- {emailSection} -
- {pictureSection} -
-
-
- ); - } -} - -UserSettingsGeneralTab.propTypes = { - intl: intlShape.isRequired, - user: React.PropTypes.object.isRequired, - updateSection: React.PropTypes.func.isRequired, - updateTab: React.PropTypes.func.isRequired, - activeSection: React.PropTypes.string.isRequired, - closeModal: React.PropTypes.func.isRequired, - collapseModal: React.PropTypes.func.isRequired -}; - -export default injectIntl(UserSettingsGeneralTab); -- cgit v1.2.3-1-g7c22