1{"version":3,"sources":["webpack://@mattermost/webapp/./actions/views/mfa.js","webpack://@mattermost/webapp/./components/user_settings/advanced/join_leave_section/join_leave_section.jsx","webpack://@mattermost/webapp/./components/user_settings/advanced/join_leave_section/index.js","webpack://@mattermost/webapp/./components/user_settings/advanced/user_settings_advanced.jsx","webpack://@mattermost/webapp/./components/user_settings/advanced/index.js","webpack://@mattermost/webapp/./components/user_settings/display/user_settings_theme/color_chooser.tsx","webpack://@mattermost/webapp/./components/user_settings/display/user_settings_theme/custom_theme_chooser.jsx","webpack://@mattermost/webapp/./components/user_settings/display/user_settings_theme/theme_thumbnail.tsx","webpack://@mattermost/webapp/./components/user_settings/display/user_settings_theme/premade_theme_chooser/premade_theme_chooser.jsx","webpack://@mattermost/webapp/./components/user_settings/display/user_settings_theme/premade_theme_chooser/index.js","webpack://@mattermost/webapp/./components/user_settings/display/user_settings_theme/user_settings_theme.jsx","webpack://@mattermost/webapp/./components/user_settings/display/user_settings_theme/index.js","webpack://@mattermost/webapp/./components/user_settings/display/manage_timezones/manage_timezones.tsx","webpack://@mattermost/webapp/./components/user_settings/display/manage_timezones/index.ts","webpack://@mattermost/webapp/./components/user_settings/display/manage_languages/manage_languages.tsx","webpack://@mattermost/webapp/./components/user_settings/display/manage_languages/index.ts","webpack://@mattermost/webapp/./components/user_settings/display/user_settings_display.tsx","webpack://@mattermost/webapp/./components/user_settings/display/index.ts","webpack://@mattermost/webapp/./components/user_settings/general/user_settings_general.tsx","webpack://@mattermost/webapp/./components/user_settings/general/index.ts","webpack://@mattermost/webapp/./components/user_settings/notifications/desktop_notification_settings.jsx","webpack://@mattermost/webapp/./packages/mattermost-redux/src/utils/notify_props.ts","webpack://@mattermost/webapp/./components/user_settings/notifications/email_notification_setting/email_notification_setting.tsx","webpack://@mattermost/webapp/./components/user_settings/notifications/email_notification_setting/index.ts","webpack://@mattermost/webapp/./components/user_settings/notifications/manage_auto_responder.jsx","webpack://@mattermost/webapp/./components/user_settings/notifications/user_settings_notifications.jsx","webpack://@mattermost/webapp/./components/user_settings/notifications/index.js","webpack://@mattermost/webapp/./components/access_history_modal/access_history_modal.tsx","webpack://@mattermost/webapp/./components/access_history_modal/index.ts","webpack://@mattermost/webapp/./components/activity_log_modal/components/more_info.tsx","webpack://@mattermost/webapp/./components/activity_log_modal/components/activity_log.tsx","webpack://@mattermost/webapp/./components/activity_log_modal/activity_log_modal.tsx","webpack://@mattermost/webapp/./components/activity_log_modal/index.ts","webpack://@mattermost/webapp/./components/user_settings/security/mfa_section/mfa_section.tsx","webpack://@mattermost/webapp/./components/user_settings/security/mfa_section/index.ts","webpack://@mattermost/webapp/./components/user_settings/security/user_access_token_section/user_access_token_section.tsx","webpack://@mattermost/webapp/./components/user_settings/security/user_access_token_section/index.ts","webpack://@mattermost/webapp/./components/user_settings/security/user_settings_security.tsx","webpack://@mattermost/webapp/./components/user_settings/security/index.ts","webpack://@mattermost/webapp/./components/user_settings/sidebar/show_unreads_category/show_unreads_category.tsx","webpack://@mattermost/webapp/./components/user_settings/sidebar/show_unreads_category/index.ts","webpack://@mattermost/webapp/./components/user_settings/sidebar/limit_visible_gms_dms/limit_visible_gms_dms.tsx","webpack://@mattermost/webapp/./components/user_settings/sidebar/limit_visible_gms_dms/index.ts","webpack://@mattermost/webapp/./components/user_settings/sidebar/user_settings_sidebar.tsx","webpack://@mattermost/webapp/./components/user_settings/sidebar/index.ts","webpack://@mattermost/webapp/./components/user_settings/user_settings.tsx","webpack://@mattermost/webapp/./components/user_settings/index.ts","webpack://@mattermost/webapp/./packages/mattermost-redux/src/actions/timezone.ts"],"names":["activateMfa","code","dispatch","getState","currentUserId","getCurrentUserId","UserActions","deactivateMfa","generateMfaSecret","JoinLeaveSection","React","constructor","props","super","e","value","currentTarget","this","setState","joinLeaveState","section","joinLeave","onUpdateSection","actions","joinLeavePreference","category","Preferences","user_id","name","state","savePreferences","render","activeSection","AdvancedSections","title","id","defaultMessage","inputs","key","className","type","checked","onChange","handleOnChange","setting","submit","handleSubmit","saving","isSaving","server_error","serverError","updateSection","handleUpdateSection","describe","renderOnOffLabel","PropTypes","isRequired","connect","getPreference","bindActionCreators","PreReleaseFeatures","Constants","AdvancedSettingsDisplay","advancedSettings","advancedSettingsCategory","settings","send_on_ctrl_enter","sendOnCtrlEnter","code_block_ctrl_enter","codeBlockOnCtrlEnter","formatting","join_leave","preReleaseFeaturesKeys","Object","keys","enabledFeatures","as","feature","label","previewFeaturesEnabled","enablePreviewFeatures","preReleaseFeatures","showDeactivateAccountModal","String","forEach","lastIndexOf","features","push","async","preferences","currentUser","userId","Array","isArray","updateUserActive","then","error","message","data","revokeAllSessionsForUser","emitUserLoggedOutEvent","getStateFromProps","description","default","t","mac","Utils","ctrlSendTitle","ctrlSendDesc","updateSetting","bind","enabled","renderCtrlEnterLabel","ctrlEnter","codeBlockCtrlEnter","renderFeatureLabel","ctrlSendSection","getCtrlSendText","ctrlSendActive","formattingSection","renderFormattingSection","previewFeaturesSection","previewFeaturesSectionDivider","formattingSectionDivider","length","toggleFeature","target","saveEnabledFeatures","values","count","deactivateAccountSection","makeConfirmationModal","auth_service","enableUserDeactivation","saveButtonText","handleShowDeactivateAccountModal","confirmButtonClass","deactivateMemberButton","show","confirmButtonText","onConfirm","handleDeactivateAccountSubmit","onCancel","handleHideDeactivateAccountModal","data-dismiss","aria-label","onClick","closeModal","aria-hidden","ref","collapseModal","getAdvancedSettingsCategory","makeGetCategory","config","getConfig","EnablePreviewFeatures","EnableUserDeactivation","get","getCurrentUser","ColorChooser","newColor","messages","defineMessages","sidebarBg","sidebarText","sidebarHeaderBg","sidebarTeamBarBg","sidebarHeaderTextColor","sidebarUnreadText","sidebarTextHoverBg","sidebarTextActiveBorder","sidebarTextActiveColor","onlineIndicator","awayIndicator","dndIndicator","mentionBg","mentionColor","centerChannelBg","centerChannelColor","newMessageSeparator","linkColor","buttonBg","buttonColor","errorTextColor","mentionHighlightBg","mentionHighlightLink","codeTheme","CustomThemeChooser","settingId","color","updateTheme","theme","newTheme","mentionBj","copyTheme","setCopyTheme","text","window","clipboardData","getData","JSON","parse","err","setThemeDefaults","stringify","stopPropagation","textarea","refs","focus","setSelectionRange","preventDefault","sidebarStylesHeader","classList","toggle","toggleSection","sidebarStyles","centerChannelStylesHeader","centerChannelStyles","linkAndButtonStylesHeader","linkAndButtonStyles","selectTheme","document","execCommand","showCopySuccess","copySuccess","querySelector","style","display","setTimeout","assign","image","node","ontransitionend","contains","overflowY","sidebarElements","centerChannelElements","linkAndButtonElements","element","index","codeThemeOptions","codeThemeURL","themes","codeThemeIndex","iconURL","uiName","popoverContent","popoverStyle","width","alt","src","defaultValue","onCodeThemeChange","placement","overlay","group","handleColorChange","pasteBox","onCopy","onPaste","pasteBoxChange","onChangeHandle","role","toggleSidebarStyles","toggleCenterChannelStyles","toggleLinkAndButtonStyles","ThemeThumbnail","themeName","themeKey","height","viewBox","fill","xmlns","aria-labelledby","x","y","rx","cx","cy","r","PremadeThemeChooser","premadeThemes","allowedThemes","hasAllowedThemes","trim","k","indexOf","premadeTheme","activeClass","replace","changeOpacity","propTypes","defaultProps","AllowedThemes","split","ThemeSetting","teamId","applyToAllTeams","currentTeamId","saveTheme","deleteTeamSpecificThemes","setRequireConfirm","originalTheme","themeChanged","field","hasOwnProperty","AppDispatcher","ActionTypes","callback","setEnforceFocus","componentDidMount","selected","$","ReactDOM","addClass","componentDidUpdate","prevProps","resetFields","removeClass","componentWillUnmount","showAllTeamsCheckbox","updateType","displayCustom","custom","premade","themeUI","allowCustomThemes","href","rel","handleImportModal","allTeamsCheckbox","submitExtra","submitTheme","disableEnterSubmit","getThemeCategory","getCurrentTeamId","getTheme","getMyTeamsCount","UserSettingsTheme","ManageTimezones","selectedOption","manualTimezone","useAutomaticTimezone","automaticTimezone","oldUseAutomaticTimezone","oldAutomaticTimezone","oldManualTimezone","timezoneNotChanged","submitUser","user","timezone","toString","updatedUser","updateMe","res","Error","timezoneLabel","selectedOptionValue","getBrowserTimezone","getTimezoneLabel","timezones","openMenu","timeOptions","map","timeObject","utc","reactStyles","menuPortal","provided","zIndex","noTimezonesFromServer","automaticTimezoneInput","handleAutomaticTimezone","disabled","manualTimezoneInput","classNamePrefix","menuPortalTarget","body","styles","options","clearable","isDisabled","containerStyle","changeTimezone","ManageLanguage","modalBody","isKeyPressed","remove","add","locale","locales","I18n","userLocale","reactSelectContainer","current","addEventListener","handleContainerKeyDown","removeEventListener","l","order","sort","a","b","lang","input","menuIsOpen","setLanguage","onKeyDown","handleKeyDown","onMenuClose","handleMenuClose","onMenuOpen","handleMenuOpen","changeLanguage","ManageLanguages","getDisplayStateFromProps","militaryTime","teammateNameDisplay","availabilityStatusOnPosts","channelDisplayMode","messageDisplay","collapseDisplay","collapsedReplyThreads","linkPreviewDisplay","UserSettingsDisplay","timePreference","CATEGORY_DISPLAY_SETTINGS","USE_MILITARY_TIME","availabilityStatusOnPostsPreference","AVAILABILITY_STATUS_ON_POSTS","teammateNameDisplayPreference","NAME_NAME_FORMAT","channelDisplayModePreference","CHANNEL_DISPLAY_MODE","messageDisplayPreference","MESSAGE_DISPLAY","collapseDisplayPreference","COLLAPSE_DISPLAY","collapsedReplyThreadsPreference","COLLAPSED_REPLY_THREADS","linkPreviewDisplayPreference","LINK_PREVIEW_DISPLAY","trackChangeIfNecessary","updateState","newState","prevSections","clock","linkpreview","message_display","channel_display_mode","languages","enableTimezone","shouldAutoUpdateTimezone","autoUpdateTimezone","preference","oldValue","trackEvent","handleChannelDisplayModeRadio","handlemessageDisplayRadio","handleCollapseRadio","handleCollapseReplyThreadsRadio","handleLinkPreviewRadio","createSection","firstOption","secondOption","thirdOption","extraInfo","firstMessage","radionButtonText","moreColon","firstMessageMore","moreId","moreMessage","secondMessage","secondMessageMore","thirdMessage","messageTitle","messageDesc","format","firstDisplay","secondDisplay","thirdSection","thirdDisplay","collapseSection","defaultDisplay","linkPreviewSection","enableLinkPreviews","clockSection","teammateNameDisplaySection","lockTeammateNameDisplay","configTeammateNameDisplay","availabilityStatusOnPostsSection","timezoneSelection","userTimezone","Boolean","messageDisplaySection","MESSAGE_DISPLAY_CLEAN","MESSAGE_DISPLAY_COMPACT","collapsedReplyThreadsAllowUserPreference","COLLAPSED_REPLY_THREADS_FALLBACK_DEFAULT","COLLAPSED_REPLY_THREADS_ON","COLLAPSED_REPLY_THREADS_OFF","channelDisplayModeSection","CHANNEL_DISPLAY_MODE_FULL_SCREEN","CHANNEL_DISPLAY_MODE_CENTERED","languagesSection","themeSection","defaultClientLocale","enableThemeSelection","currentUserTimezone","getUserTimezone","automaticTimezoneNotSet","AllowCustomThemes","EnableLinkPreviews","DefaultClientLocale","EnableThemeSelection","ExperimentalTimezone","getLicense","LockTeammateNameDisplay","TeammateNameDisplay","getUserCurrentTimezone","isCollapsedThreadsAllowed","CollapsedThreads","getCollapsedThreadsPreference","holders","usernameReserved","usernameRestrictions","validEmail","emailMatch","incorrectPassword","emptyPassword","validImage","imageTooLarge","uploadImage","uploadImageMobile","fullName","nickname","username","profilePicture","close","position","UserSettingsGeneralTab","email","resendStatus","showSpinner","sendVerificationEmail","loading","handleEmailResend","toLowerCase","formatMessage","intl","usernameError","errObj","ValidationErrors","clientError","min","max","firstName","lastName","first_name","last_name","confirmEmail","currentPassword","isEmail","password","emailError","emailUpdated","sectionIsSaving","getMe","requireEmailVerification","clearErrors","logError","AnnouncementBarMessages","AnnouncementBarTypes","server_error_id","setDefaultProfileImage","submitActive","pictureFile","file","AcceptedProfileImageTypes","size","maxFileSize","loadingPicture","uploadProfileImage","setupInitialState","files","originalEmail","createEmailSection","emailSection","emailVerificationEnabled","helpText","autoFocus","updateEmail","maxLength","updateConfirmEmail","updateCurrentPassword","submitEmail","nameSection","ldapFirstNameAttributeSet","ldapLastNameAttributeSet","samlFirstNameAttributeSet","samlLastNameAttributeSet","updateFirstName","onFocus","updateLastName","notifClick","updateTab","notifLink","notify","submitName","nicknameSection","usernameSection","positionSection","ldapNicknameAttributeSet","samlNicknameAttributeSet","nicknameLabel","updateNickname","autoCapitalize","submitNickname","usernameLabel","updateUsername","submitUsername","ldapPositionAttributeSet","samlPositionAttributeSet","positionLabel","updatePosition","submitPosition","pictureSection","setDefault","imgSrc","ldapPictureAttributeSet","submitPicture","last_picture_update","setDefaultProfilePicture","onSubmit","onSetDefault","defaultImageSrc","onFileChange","updatePicture","minMessage","date","FormattedDate","Date","day","month","year","injectIntl","RequireEmailVerification","parseInt","MaxFileSize","LdapFirstNameAttributeSet","LdapLastNameAttributeSet","SamlFirstNameAttributeSet","SamlLastNameAttributeSet","LdapNicknameAttributeSet","SamlNicknameAttributeSet","SamlPositionAttributeSet","LdapPositionAttributeSet","LdapPictureAttributeSet","DesktopNotificationSettings","cancel","getAttribute","setParentState","NotificationLevels","activityRadio","soundSection","notificationSelection","threadsNotificationSelection","activity","soundRadio","sound","from","isDesktopApp","desktop","semver","version","setDesktopNotificationSound","isSearchable","dropdownSoundRef","data-key","data-value","isCollapsedThreadsEnabled","threads","handleThreadsOnChange","handleMaxUpdateSection","formattedMessageProps","hasSoundOption","focused","handleMinUpdateSection","selectedSound","blurDropdown","blur","active","buildMaximizedSetting","buildMinimizedSetting","getEmailInterval","enableEmailNotification","enableEmailBatching","emailIntervalPreference","INTERVAL_NEVER","INTERVAL_IMMEDIATE","INTERVAL_FIFTEEN_MINUTES","INTERVAL_HOUR","validValuesWithoutEmailBatching","EmailNotificationSetting","enableEmail","newInterval","emailInterval","sendEmailNotifications","localizeMessage","batchingOptions","batchingInfo","data-enable-email","data-email-interval","handleChange","nextProps","prevState","renderMinSettingView","renderMaxSettingView","EnableEmailBatching","SendEmailNotifications","ManageAutoResponder","autoResponderActive","autoResponderMessage","activeToggle","handleAutoResponderChecked","resize","rows","placeholder","onMessageChanged","shiftEnter","getNotificationsStateFromProps","desktopThreads","pushThreads","emailThreads","desktopNotificationSound","comments","pushActivity","pushStatus","notify_props","desktop_threads","push_threads","email_threads","desktop_sound","desktop_notification_sound","push_status","auto_responder_active","auto_responder_message","usernameKey","customKeys","firstNameKey","channelKey","mention_keys","splice","join","channel","desktopActivity","desktopSound","customKeysChecked","notifyCommentsLevel","NotificationsTab","mentionKeys","stringKeys","result","handleCancel","val","customCheckRef","customMentionsRef","updateCustomMentionKeys","sendPushNotifications","pushActivityRadio","pushStatusRadio","pushStatusSettings","pushThreadsNotificationSelection","handleNotifyPushThread","handlePushStatusRadio","handlePushRadio","drawerRef","wrapperRef","handleNotifyCommentsRadio","keysSection","commentsSection","autoResponderSection","handleUpdateFirstNameKey","updateFirstNameKey","handleUpdateUsernameKey","updateUsernameKey","handleUpdateChannelKey","updateChannelKey","onCustomChange","concat","i","substring","commentsActive","enableAutoResponder","setStateValue","pushNotificationSection","createPushNotificationSection","handleEmailRadio","activeTab","SendPushNotifications","ExperimentalEnableAutomaticReplies","UserSettingsNotifications","AccessHistoryModal","getUserAudits","onShow","content","userAudits","audits","showIp","showSession","Modal","dialogClassName","onHide","onExited","bsSize","closeButton","componentClass","getCurrentUserAudits","MoreInfo","currentSession","handleMoreInfo","moreInfo","firstAccessTime","create_at","getMonthLong","time","FormattedTime","hour","minute","os","browser","ActivityLog","submitRevoke","session","device_id","includes","deviceTypeId","deviceTypeMessage","devicePicture","deviceTitle","General","devicePlatform","lastAccessTime","last_activity_at","platform","isMobileSession","sessionInfo","mobileSessionInfo","ActivityLogModal","altId","modalContent","closest","revokeSession","getSessions","activityList","sessions","reduce","array","getUserSessions","getCurrentLocale","MfaSection","browserHistory","mfaEnforced","mfaActive","buttonText","removeMfa","setupMfa","renderTitle","mfaAvailable","renderContent","renderHelpText","renderDescription","license","mfaLicensed","IsLicensed","MFA","mfaEnabled","EnableMultifactorAuthentication","EnforceMultifactorAuthentication","mfa_active","TOKEN_CREATING","TOKEN_CREATED","TOKEN_NOT_CREATING","UserAccessTokenSection","tokenCreationState","handleCancelConfirm","newtokendescriptionRef","tokenError","confirmCopyToken","createUserAccessToken","newToken","confirmAction","showConfirmModal","confirmTitle","confirmMessage","token","confirmButton","confirmComplete","confirmHideCancel","UserUtils","roles","handleCreateToken","confirmCreateToken","tokenId","userAccessTokens","revokeToken","revokeUserAccessToken","enableUserAccessToken","disableUserAccessToken","clearUserAccessTokens","getUserAccessTokensForUser","tokenListClass","tokenList","noTokenText","newTokenSection","activeLink","activeStatus","is_active","deactivateToken","activateToken","confirmRevokeToken","isMobile","onKeyPress","saveTokenKeyPress","btnClass","savingMessage","stopCreatingToken","additionalClassName","startCreatingToken","infoPosition","cancelButtonText","hideCancel","entities","users","myUserAccessTokens","SECTION_PASSWORD","SECTION_SIGNIN","SECTION_APPS","SECTION_TOKENS","SecurityTab","getAuthorizedOAuthApps","authorizedApps","newPassword","confirmPassword","passwordError","valid","passwordConfig","defaultState","getDefaultState","savingPassword","updateUserPassword","appId","deauthorizeOAuthApp","filter","app","submitPassword","updateNewPassword","updateConfirmPassword","d","last_password_update","hour12","emailOption","gitlabOption","googleOption","office365Option","openidOption","ldapOption","samlOption","enableSignUpWithGitLab","Link","to","encodeURIComponent","enableSignUpWithGoogle","enableSignUpWithOffice365","enableSignUpWithOpenId","enableLdap","enableSaml","enableSignUpWithEmail","link","apps","homepage","data-app","deauthorizeApp","icon_url","icon50","wrapperClass","authService","enableOAuthServiceProvider","loadAuthorizedOAuthApps","passwordSection","createPasswordSection","signInSection","oauthSection","tokensSection","numMethods","experimentalEnableAuthenticationTransfer","createSignInSection","createOAuthAppsSection","canUseAccessTokens","ariaLabel","dialogType","ownProps","tokensEnabled","EnableUserAccessTokens","userHasTokenRole","EnableOAuthServiceProvider","EnableSignUpWithEmail","EnableSignUpWithGitLab","EnableSignUpWithGoogle","EnableSignUpWithOpenId","EnableLdap","EnableSaml","EnableSignUpWithOffice365","ExperimentalEnableAuthenticationTransfer","getPasswordConfig","getBool","ShowUnreadsCategory","showUnreadsCategory","data-testid","mapDispatchToProps","shouldShowUnreadsCategory","limits","LimitVisibleGMsDMs","limit","find","dmGmLimit","getInt","UserSettingsSidebar","UserSettings","deviceTimezone","currentUer","currentTimezone","newTimezoneExists"],"mappings":"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","file":"654.53a13f4e3ddbeb75380d.js","sourcesContent":["// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.\n// See LICENSE.txt for license information.\n\nimport * as UserActions from 'mattermost-redux/actions/users';\nimport {getCurrentUserId} from 'mattermost-redux/selectors/entities/users';\n\nexport function activateMfa(code) {\n return (dispatch, getState) => {\n const currentUserId = getCurrentUserId(getState());\n\n return dispatch(UserActions.updateUserMfa(currentUserId, true, code));\n };\n}\n\nexport function deactivateMfa() {\n return (dispatch, getState) => {\n const currentUserId = getCurrentUserId(getState());\n\n return dispatch(UserActions.updateUserMfa(currentUserId, false));\n };\n}\n\nexport function generateMfaSecret() {\n return (dispatch, getState) => {\n const currentUserId = getCurrentUserId(getState());\n\n return dispatch(UserActions.generateMfaSecret(currentUserId));\n };\n}\n\n","// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.\n// See LICENSE.txt for license information.\n\nimport React from 'react';\nimport PropTypes from 'prop-types';\nimport {FormattedMessage} from 'react-intl';\n\nimport {Preferences} from 'mattermost-redux/constants';\n\nimport SettingItemMax from 'components/setting_item_max.jsx';\nimport SettingItemMin from 'components/setting_item_min';\n\nimport {AdvancedSections} from 'utils/constants';\n\nexport default class JoinLeaveSection extends React.PureComponent {\n static propTypes = {\n activeSection: PropTypes.string,\n currentUserId: PropTypes.string.isRequired,\n joinLeave: PropTypes.string,\n onUpdateSection: PropTypes.func.isRequired,\n renderOnOffLabel: PropTypes.func.isRequired,\n actions: PropTypes.shape({\n savePreferences: PropTypes.func.isRequired,\n }).isRequired,\n }\n\n constructor(props) {\n super(props);\n\n this.state = {\n joinLeaveState: props.joinLeave,\n };\n }\n\n handleOnChange = (e) => {\n const value = e.currentTarget.value;\n\n this.setState({joinLeaveState: value});\n }\n\n handleUpdateSection = (section) => {\n if (!section) {\n this.setState({joinLeaveState: this.props.joinLeave});\n }\n\n this.props.onUpdateSection(section);\n }\n\n handleSubmit = () => {\n const {actions, currentUserId, onUpdateSection} = this.props;\n const joinLeavePreference = {category: Preferences.CATEGORY_ADVANCED_SETTINGS, user_id: currentUserId, name: Preferences.ADVANCED_FILTER_JOIN_LEAVE, value: this.state.joinLeaveState};\n actions.savePreferences(currentUserId, [joinLeavePreference]);\n\n onUpdateSection();\n }\n\n render() {\n const {joinLeaveState} = this.state;\n if (this.props.activeSection === AdvancedSections.JOIN_LEAVE) {\n return (\n <SettingItemMax\n title={\n <FormattedMessage\n id='user.settings.advance.joinLeaveTitle'\n defaultMessage='Enable Join/Leave Messages'\n />\n }\n inputs={[\n <fieldset key='joinLeaveSetting'>\n <legend className='form-legend hidden-label'>\n <FormattedMessage\n id='user.settings.advance.joinLeaveTitle'\n defaultMessage='Enable Join/Leave Messages'\n />\n </legend>\n <div className='radio'>\n <label>\n <input\n id='joinLeaveOn'\n type='radio'\n value={'true'}\n name={AdvancedSections.JOIN_LEAVE}\n checked={joinLeaveState === 'true'}\n onChange={this.handleOnChange}\n />\n <FormattedMessage\n id='user.settings.advance.on'\n defaultMessage='On'\n />\n </label>\n <br/>\n </div>\n <div className='radio'>\n <label>\n <input\n id='joinLeaveOff'\n type='radio'\n value={'false'}\n name={AdvancedSections.JOIN_LEAVE}\n checked={joinLeaveState === 'false'}\n onChange={this.handleOnChange}\n />\n <FormattedMessage\n id='user.settings.advance.off'\n defaultMessage='Off'\n />\n </label>\n <br/>\n </div>\n <div className='mt-5'>\n <FormattedMessage\n id='user.settings.advance.joinLeaveDesc'\n defaultMessage='When \"On\", System Messages saying a user has joined or left a channel will be visible. When \"Off\", the System Messages about joining or leaving a channel will be hidden. A message will still show up when you are added to a channel, so you can receive a notification.'\n />\n </div>\n </fieldset>,\n ]}\n setting={AdvancedSections.JOIN_LEAVE}\n submit={this.handleSubmit}\n saving={this.state.isSaving}\n server_error={this.state.serverError}\n updateSection={this.handleUpdateSection}\n />\n );\n }\n\n return (\n <SettingItemMin\n title={\n <FormattedMessage\n id='user.settings.advance.joinLeaveTitle'\n defaultMessage='Enable Join/Leave Messages'\n />\n }\n describe={this.props.renderOnOffLabel(joinLeaveState)}\n section={AdvancedSections.JOIN_LEAVE}\n updateSection={this.handleUpdateSection}\n />\n );\n }\n}\n","// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.\n// See LICENSE.txt for license information.\n\nimport {bindActionCreators} from 'redux';\nimport {connect} from 'react-redux';\n\nimport {savePreferences} from 'mattermost-redux/actions/preferences';\nimport {Preferences} from 'mattermost-redux/constants';\nimport {get as getPreference} from 'mattermost-redux/selectors/entities/preferences';\nimport {getCurrentUserId} from 'mattermost-redux/selectors/entities/users';\n\nimport JoinLeaveSection from './join_leave_section.jsx';\n\nfunction mapStateToProps(state) {\n const joinLeave = getPreference(\n state,\n Preferences.CATEGORY_ADVANCED_SETTINGS,\n Preferences.ADVANCED_FILTER_JOIN_LEAVE,\n 'true',\n );\n\n return {\n currentUserId: getCurrentUserId(state),\n joinLeave,\n };\n}\n\nfunction mapDispatchToProps(dispatch) {\n return {\n actions: bindActionCreators({\n savePreferences,\n }, dispatch),\n };\n}\n\nexport default connect(mapStateToProps, mapDispatchToProps)(JoinLeaveSection);\n","// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.\n// See LICENSE.txt for license information.\n/* eslint-disable react/no-string-refs */\n\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport {FormattedMessage} from 'react-intl';\n\nimport {emitUserLoggedOutEvent} from 'actions/global_actions';\nimport Constants from 'utils/constants';\nimport * as Utils from 'utils/utils.jsx';\nimport {t} from 'utils/i18n';\nimport SettingItemMax from 'components/setting_item_max.jsx';\nimport SettingItemMin from 'components/setting_item_min';\nimport ConfirmModal from 'components/confirm_modal';\nimport BackIcon from 'components/widgets/icons/fa_back_icon';\n\nimport JoinLeaveSection from './join_leave_section';\n\nconst PreReleaseFeatures = Constants.PRE_RELEASE_FEATURES;\n\nexport default class AdvancedSettingsDisplay extends React.PureComponent {\n static propTypes = {\n currentUser: PropTypes.object.isRequired,\n advancedSettingsCategory: PropTypes.array.isRequired,\n sendOnCtrlEnter: PropTypes.string.isRequired,\n codeBlockOnCtrlEnter: PropTypes.bool,\n formatting: PropTypes.string.isRequired,\n joinLeave: PropTypes.string.isRequired,\n updateSection: PropTypes.func,\n activeSection: PropTypes.string,\n closeModal: PropTypes.func.isRequired,\n collapseModal: PropTypes.func.isRequired,\n enablePreviewFeatures: PropTypes.bool,\n enableUserDeactivation: PropTypes.bool,\n actions: PropTypes.shape({\n savePreferences: PropTypes.func.isRequired,\n updateUserActive: PropTypes.func.isRequired,\n revokeAllSessionsForUser: PropTypes.func.isRequired,\n }).isRequired,\n }\n\n constructor(props) {\n super(props);\n\n this.state = this.getStateFromProps();\n }\n\n getStateFromProps = () => {\n const advancedSettings = this.props.advancedSettingsCategory;\n const settings = {\n send_on_ctrl_enter: this.props.sendOnCtrlEnter,\n code_block_ctrl_enter: this.props.codeBlockOnCtrlEnter,\n formatting: this.props.formatting,\n join_leave: this.props.joinLeave,\n };\n\n const preReleaseFeaturesKeys = Object.keys(PreReleaseFeatures);\n let enabledFeatures = 0;\n for (const as of advancedSettings) {\n for (const key of preReleaseFeaturesKeys) {\n const feature = PreReleaseFeatures[key];\n\n if (as.name === Constants.FeatureTogglePrefix + feature.label) {\n settings[as.name] = as.value;\n\n if (as.value === 'true') {\n enabledFeatures += 1;\n }\n }\n }\n }\n\n const isSaving = false;\n\n const previewFeaturesEnabled = this.props.enablePreviewFeatures;\n const showDeactivateAccountModal = false;\n\n return {\n preReleaseFeatures: PreReleaseFeatures,\n settings,\n preReleaseFeaturesKeys,\n enabledFeatures,\n isSaving,\n previewFeaturesEnabled,\n showDeactivateAccountModal,\n };\n }\n\n updateSetting = (setting, value) => {\n const settings = this.state.settings;\n settings[setting] = value;\n this.setState(settings);\n }\n\n toggleFeature = (feature, checked) => {\n const settings = this.state.settings;\n settings[Constants.FeatureTogglePrefix + feature] = String(checked);\n\n let enabledFeatures = 0;\n Object.keys(this.state.settings).forEach((setting) => {\n if (setting.lastIndexOf(Constants.FeatureTogglePrefix) === 0 && this.state.settings[setting] === 'true') {\n enabledFeatures++;\n }\n });\n\n this.setState({settings, enabledFeatures});\n }\n\n saveEnabledFeatures = () => {\n const features = [];\n Object.keys(this.state.settings).forEach((setting) => {\n if (setting.lastIndexOf(Constants.FeatureTogglePrefix) === 0) {\n features.push(setting);\n }\n });\n\n this.handleSubmit(features);\n }\n\n handleSubmit = async (settings) => {\n const preferences = [];\n const {actions, currentUser} = this.props;\n const userId = currentUser.id;\n\n // this should be refactored so we can actually be certain about what type everything is\n (Array.isArray(settings) ? settings : [settings]).forEach((setting) => {\n preferences.push({\n user_id: userId,\n category: Constants.Preferences.CATEGORY_ADVANCED_SETTINGS,\n name: setting,\n value: this.state.settings[setting],\n });\n });\n\n this.setState({isSaving: true});\n await actions.savePreferences(userId, preferences);\n\n this.handleUpdateSection('');\n }\n\n handleDeactivateAccountSubmit = async () => {\n const userId = this.props.currentUser.id;\n\n this.setState({isSaving: true});\n\n this.props.actions.updateUserActive(userId, false).\n then(({error}) => {\n if (error) {\n this.setState({serverError: error.message});\n }\n });\n\n const {data, error} = await this.props.actions.revokeAllSessionsForUser(userId);\n if (data) {\n emitUserLoggedOutEvent();\n } else if (error) {\n this.setState({serverError: error.message});\n }\n }\n\n handleShowDeactivateAccountModal = () => {\n this.setState({\n showDeactivateAccountModal: true,\n });\n }\n\n handleHideDeactivateAccountModal = () => {\n this.setState({\n showDeactivateAccountModal: false,\n });\n }\n\n handleUpdateSection = (section) => {\n if (!section) {\n this.setState(this.getStateFromProps());\n }\n this.setState({isSaving: false});\n this.props.updateSection(section);\n }\n\n // This function changes ctrl to cmd when OS is mac\n getCtrlSendText = () => {\n const description = {\n default: {\n id: t('user.settings.advance.sendDesc'),\n defaultMessage: 'When enabled, CTRL + ENTER will send the message and ENTER inserts a new line.',\n },\n mac: {\n id: t('user.settings.advance.sendDesc.mac'),\n defaultMessage: 'When enabled, ⌘ + ENTER will send the message and ENTER inserts a new line.',\n },\n };\n const title = {\n default: {\n id: t('user.settings.advance.sendTitle'),\n defaultMessage: 'Send Messages on CTRL+ENTER',\n },\n mac: {\n id: t('user.settings.advance.sendTitle.mac'),\n defaultMessage: 'Send Messages on ⌘+ENTER',\n },\n };\n if (Utils.isMac()) {\n return {\n ctrlSendTitle: title.mac,\n ctrlSendDesc: description.mac,\n };\n }\n return {\n ctrlSendTitle: title.default,\n ctrlSendDesc: description.default,\n };\n }\n\n renderOnOffLabel(enabled) {\n if (enabled === 'false') {\n return (\n <FormattedMessage\n id='user.settings.advance.off'\n defaultMessage='Off'\n />\n );\n }\n\n return (\n <FormattedMessage\n id='user.settings.advance.on'\n defaultMessage='On'\n />\n );\n }\n\n renderCtrlEnterLabel() {\n const ctrlEnter = this.state.settings.send_on_ctrl_enter;\n const codeBlockCtrlEnter = this.state.settings.code_block_ctrl_enter;\n if (ctrlEnter === 'false' && codeBlockCtrlEnter === 'false') {\n return (\n <FormattedMessage\n id='user.settings.advance.off'\n defaultMessage='Off'\n />\n );\n } else if (ctrlEnter === 'true' && codeBlockCtrlEnter === 'true') {\n return (\n <FormattedMessage\n id='user.settings.advance.onForAllMessages'\n defaultMessage='On for all messages'\n />\n );\n }\n return (\n <FormattedMessage\n id='user.settings.advance.onForCode'\n defaultMessage='On only for code blocks starting with ```'\n />\n );\n }\n\n renderFormattingSection = () => {\n if (this.props.activeSection === 'formatting') {\n return (\n <SettingItemMax\n title={\n <FormattedMessage\n id='user.settings.advance.formattingTitle'\n defaultMessage='Enable Post Formatting'\n />\n }\n inputs={[\n <fieldset key='formattingSetting'>\n <legend className='form-legend hidden-label'>\n <FormattedMessage\n id='user.settings.advance.formattingTitle'\n defaultMessage='Enable Post Formatting'\n />\n </legend>\n <div className='radio'>\n <label>\n <input\n id='postFormattingOn'\n type='radio'\n name='formatting'\n checked={this.state.settings.formatting !== 'false'}\n onChange={this.updateSetting.bind(this, 'formatting', 'true')}\n />\n <FormattedMessage\n id='user.settings.advance.on'\n defaultMessage='On'\n />\n </label>\n <br/>\n </div>\n <div className='radio'>\n <label>\n <input\n id='postFormattingOff'\n type='radio'\n name='formatting'\n checked={this.state.settings.formatting === 'false'}\n onChange={this.updateSetting.bind(this, 'formatting', 'false')}\n />\n <FormattedMessage\n id='user.settings.advance.off'\n defaultMessage='Off'\n />\n </label>\n <br/>\n </div>\n <div className='mt-5'>\n <FormattedMessage\n id='user.settings.advance.formattingDesc'\n defaultMessage='If enabled, posts will be formatted to create links, show emoji, style the text, and add line breaks. By default, this setting is enabled.'\n />\n </div>\n </fieldset>,\n ]}\n setting={'formatting'}\n submit={this.handleSubmit}\n saving={this.state.isSaving}\n server_error={this.state.serverError}\n updateSection={this.handleUpdateSection}\n />\n );\n }\n\n return (\n <SettingItemMin\n title={\n <FormattedMessage\n id='user.settings.advance.formattingTitle'\n defaultMessage='Enable Post Formatting'\n />\n }\n describe={this.renderOnOffLabel(this.state.settings.formatting)}\n section={'formatting'}\n updateSection={this.handleUpdateSection}\n />\n );\n }\n\n renderFeatureLabel(feature) {\n switch (feature) {\n case 'MARKDOWN_PREVIEW':\n return (\n <FormattedMessage\n id='user.settings.advance.markdown_preview'\n defaultMessage='Show markdown preview option in message input box'\n />\n );\n default:\n return null;\n }\n }\n\n render() {\n const serverError = this.state.serverError || null;\n let ctrlSendSection;\n const {ctrlSendTitle, ctrlSendDesc} = this.getCtrlSendText();\n\n if (this.props.activeSection === 'advancedCtrlSend') {\n const ctrlSendActive = [\n this.state.settings.send_on_ctrl_enter === 'true',\n this.state.settings.send_on_ctrl_enter === 'false' && this.state.settings.code_block_ctrl_enter === 'true',\n this.state.settings.send_on_ctrl_enter === 'false' && this.state.settings.code_block_ctrl_enter === 'false',\n ];\n\n const inputs = [\n <fieldset key='ctrlSendSetting'>\n <legend className='form-legend hidden-label'>\n <FormattedMessage {...ctrlSendTitle}/>\n </legend>\n <div className='radio'>\n <label>\n <input\n id='ctrlSendOn'\n type='radio'\n name='sendOnCtrlEnter'\n checked={ctrlSendActive[0]}\n onChange={() => {\n this.updateSetting('send_on_ctrl_enter', 'true');\n this.updateSetting('code_block_ctrl_enter', 'true');\n }}\n />\n <FormattedMessage\n id='user.settings.advance.onForAllMessages'\n defaultMessage='On for all messages'\n />\n </label>\n <br/>\n </div>\n <div className='radio'>\n <label>\n <input\n id='ctrlSendOnForCode'\n type='radio'\n name='sendOnCtrlEnter'\n checked={ctrlSendActive[1]}\n onChange={() => {\n this.updateSetting('send_on_ctrl_enter', 'false');\n this.updateSetting('code_block_ctrl_enter', 'true');\n }}\n />\n <FormattedMessage\n id='user.settings.advance.onForCode'\n defaultMessage='On only for code blocks starting with ```'\n />\n </label>\n <br/>\n </div>\n <div className='radio'>\n <label>\n <input\n id='ctrlSendOff'\n type='radio'\n name='sendOnCtrlEnter'\n checked={ctrlSendActive[2]}\n onChange={() => {\n this.updateSetting('send_on_ctrl_enter', 'false');\n this.updateSetting('code_block_ctrl_enter', 'false');\n }}\n />\n <FormattedMessage\n id='user.settings.advance.off'\n defaultMessage='Off'\n />\n </label>\n <br/>\n </div>\n <div>\n <br/>\n <FormattedMessage {...ctrlSendDesc}/>\n </div>\n </fieldset>,\n ];\n ctrlSendSection = (\n <SettingItemMax\n title={\n <FormattedMessage {...ctrlSendTitle}/>\n }\n inputs={inputs}\n submit={this.handleSubmit.bind(this, ['send_on_ctrl_enter', 'code_block_ctrl_enter'])}\n saving={this.state.isSaving}\n server_error={serverError}\n updateSection={this.handleUpdateSection}\n />\n );\n } else {\n ctrlSendSection = (\n <SettingItemMin\n title={\n <FormattedMessage {...ctrlSendTitle}/>\n }\n describe={this.renderCtrlEnterLabel()}\n section={'advancedCtrlSend'}\n updateSection={this.handleUpdateSection}\n />\n );\n }\n\n const formattingSection = this.renderFormattingSection();\n let formattingSectionDivider = null;\n if (formattingSection) {\n formattingSectionDivider = <div className='divider-light'/>;\n }\n\n let previewFeaturesSection;\n let previewFeaturesSectionDivider;\n if (this.state.previewFeaturesEnabled && this.state.preReleaseFeaturesKeys.length > 0) {\n previewFeaturesSectionDivider = (\n <div className='divider-light'/>\n );\n\n if (this.props.activeSection === 'advancedPreviewFeatures') {\n const inputs = [];\n\n this.state.preReleaseFeaturesKeys.forEach((key) => {\n const feature = this.state.preReleaseFeatures[key];\n inputs.push(\n <div key={'advancedPreviewFeatures_' + feature.label}>\n <div className='checkbox'>\n <label>\n <input\n id={'advancedPreviewFeatures' + feature.label}\n type='checkbox'\n checked={this.state.settings[Constants.FeatureTogglePrefix + feature.label] === 'true'}\n onChange={(e) => {\n this.toggleFeature(feature.label, e.target.checked);\n }}\n />\n {this.renderFeatureLabel(key)}\n </label>\n </div>\n </div>,\n );\n });\n\n inputs.push(\n <div key='advancedPreviewFeatures_helptext'>\n <br/>\n <FormattedMessage\n id='user.settings.advance.preReleaseDesc'\n defaultMessage=\"Check any pre-released features you'd like to preview. You may also need to refresh the page before the setting will take effect.\"\n />\n </div>,\n );\n previewFeaturesSection = (\n <SettingItemMax\n title={\n <FormattedMessage\n id='user.settings.advance.preReleaseTitle'\n defaultMessage='Preview Pre-release Features'\n />\n }\n inputs={inputs}\n submit={this.saveEnabledFeatures}\n saving={this.state.isSaving}\n server_error={serverError}\n updateSection={this.handleUpdateSection}\n />\n );\n } else {\n previewFeaturesSection = (\n <SettingItemMin\n title={Utils.localizeMessage('user.settings.advance.preReleaseTitle', 'Preview Pre-release Features')}\n describe={\n <FormattedMessage\n id='user.settings.advance.enabledFeatures'\n defaultMessage='{count, number} {count, plural, one {Feature} other {Features}} Enabled'\n values={{count: this.state.enabledFeatures}}\n />\n }\n section={'advancedPreviewFeatures'}\n updateSection={this.handleUpdateSection}\n />\n );\n }\n }\n\n let deactivateAccountSection = '';\n let makeConfirmationModal = '';\n const currentUser = this.props.currentUser;\n\n if (currentUser.auth_service === '' && this.props.enableUserDeactivation) {\n if (this.props.activeSection === 'deactivateAccount') {\n deactivateAccountSection = (\n <SettingItemMax\n title={\n <FormattedMessage\n id='user.settings.advance.deactivateAccountTitle'\n defaultMessage='Deactivate Account'\n />\n }\n inputs={[\n <div key='formattingSetting'>\n <div>\n <br/>\n <FormattedMessage\n id='user.settings.advance.deactivateDesc'\n defaultMessage='Deactivating your account removes your ability to log in to this server and disables all email and mobile notifications. To reactivate your account, contact your System Administrator.'\n />\n </div>\n </div>,\n ]}\n saveButtonText={'Deactivate'}\n setting={'deactivateAccount'}\n submit={this.handleShowDeactivateAccountModal}\n saving={this.state.isSaving}\n server_error={this.state.serverError}\n updateSection={this.handleUpdateSection}\n />\n );\n } else {\n deactivateAccountSection = (\n <SettingItemMin\n title={\n <FormattedMessage\n id='user.settings.advance.deactivateAccountTitle'\n defaultMessage='Deactivate Account'\n />\n }\n describe={\n <FormattedMessage\n id='user.settings.advance.deactivateDescShort'\n defaultMessage=\"Click 'Edit' to deactivate your account\"\n />\n }\n section={'deactivateAccount'}\n updateSection={this.handleUpdateSection}\n />\n );\n }\n\n const confirmButtonClass = 'btn btn-danger';\n const deactivateMemberButton = (\n <FormattedMessage\n id='user.settings.advance.deactivate_member_modal.deactivateButton'\n defaultMessage='Yes, deactivate my account'\n />\n );\n\n makeConfirmationModal = (\n <ConfirmModal\n show={this.state.showDeactivateAccountModal}\n title={\n <FormattedMessage\n id='user.settings.advance.confirmDeactivateAccountTitle'\n defaultMessage='Confirm Deactivation'\n />\n }\n message={\n <FormattedMessage\n id='user.settings.advance.confirmDeactivateDesc'\n defaultMessage='Are you sure you want to deactivate your account? This can only be reversed by your System Administrator.'\n />\n }\n confirmButtonClass={confirmButtonClass}\n confirmButtonText={deactivateMemberButton}\n onConfirm={this.handleDeactivateAccountSubmit}\n onCancel={this.handleHideDeactivateAccountModal}\n />\n );\n }\n\n return (\n <div>\n <div className='modal-header'>\n <button\n id='closeButton'\n type='button'\n className='close'\n data-dismiss='modal'\n aria-label='Close'\n onClick={this.props.closeModal}\n >\n <span aria-hidden='true'>{'×'}</span>\n </button>\n <h4\n className='modal-title'\n ref='title'\n >\n <div className='modal-back'>\n <span onClick={this.props.collapseModal}>\n <BackIcon/>\n </span>\n </div>\n <FormattedMessage\n id='user.settings.advance.title'\n defaultMessage='Advanced Settings'\n />\n </h4>\n </div>\n <div className='user-settings'>\n <h3 className='tab-header'>\n <FormattedMessage\n id='user.settings.advance.title'\n defaultMessage='Advanced Settings'\n />\n </h3>\n <div className='divider-dark first'/>\n {ctrlSendSection}\n {formattingSectionDivider}\n {formattingSection}\n <div className='divider-light'/>\n <JoinLeaveSection\n activeSection={this.props.activeSection}\n onUpdateSection={this.handleUpdateSection}\n renderOnOffLabel={this.renderOnOffLabel}\n />\n {previewFeaturesSectionDivider}\n {previewFeaturesSection}\n {formattingSectionDivider}\n {deactivateAccountSection}\n <div className='divider-dark'/>\n {makeConfirmationModal}\n </div>\n </div>\n );\n }\n}\n/* eslint-enable react/no-string-refs */\n","// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.\n// See LICENSE.txt for license information.\n\nimport {connect} from 'react-redux';\nimport {bindActionCreators} from 'redux';\n\nimport {getConfig} from 'mattermost-redux/selectors/entities/general';\nimport {getCurrentUser} from 'mattermost-redux/selectors/entities/users';\nimport {get, makeGetCategory} from 'mattermost-redux/selectors/entities/preferences';\nimport {savePreferences} from 'mattermost-redux/actions/preferences';\nimport {updateUserActive, revokeAllSessionsForUser} from 'mattermost-redux/actions/users';\n\nimport {Preferences} from 'utils/constants';\n\nimport AdvancedSettingsDisplay from './user_settings_advanced.jsx';\n\nfunction makeMapStateToProps() {\n const getAdvancedSettingsCategory = makeGetCategory();\n\n return (state) => {\n const config = getConfig(state);\n\n const enablePreviewFeatures = config.EnablePreviewFeatures === 'true';\n const enableUserDeactivation = config.EnableUserDeactivation === 'true';\n\n return {\n advancedSettingsCategory: getAdvancedSettingsCategory(state, Preferences.CATEGORY_ADVANCED_SETTINGS),\n sendOnCtrlEnter: get(state, Preferences.CATEGORY_ADVANCED_SETTINGS, 'send_on_ctrl_enter', 'false'),\n codeBlockOnCtrlEnter: get(state, Preferences.CATEGORY_ADVANCED_SETTINGS, 'code_block_ctrl_enter', 'true'),\n formatting: get(state, Preferences.CATEGORY_ADVANCED_SETTINGS, 'formatting', 'true'),\n joinLeave: get(state, Preferences.CATEGORY_ADVANCED_SETTINGS, 'join_leave', 'true'),\n currentUser: getCurrentUser(state),\n enablePreviewFeatures,\n enableUserDeactivation,\n };\n };\n}\n\nfunction mapDispatchToProps(dispatch) {\n return {\n actions: bindActionCreators({\n savePreferences,\n updateUserActive,\n revokeAllSessionsForUser,\n }, dispatch),\n };\n}\n\nexport default connect(makeMapStateToProps, mapDispatchToProps)(AdvancedSettingsDisplay);\n","// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.\n// See LICENSE.txt for license information.\n\nimport React from 'react';\n\nimport ColorInput from 'components/color_input';\n\ntype Props = {\n id: string;\n label: React.ReactNode;\n value: string;\n onChange?: (id: string, newColor: string) => void;\n}\n\nexport default function ColorChooser(props: Props) {\n const handleChange = (newColor: string) => {\n props.onChange?.(props.id, newColor);\n };\n\n return (\n <React.Fragment>\n <label className='custom-label'>{props.label}</label>\n <ColorInput\n id={props.id}\n value={props.value}\n onChange={handleChange}\n />\n </React.Fragment>\n );\n}\n","// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.\n// See LICENSE.txt for license information.\n/* eslint-disable react/no-string-refs */\n\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport {defineMessages, FormattedMessage} from 'react-intl';\n\nimport {setThemeDefaults} from 'mattermost-redux/utils/theme_utils';\n\nimport {t} from 'utils/i18n';\n\nimport Constants from 'utils/constants';\n\nimport LocalizedIcon from 'components/localized_icon';\nimport OverlayTrigger from 'components/overlay_trigger';\nimport Popover from 'components/widgets/popover';\n\nimport ColorChooser from './color_chooser';\n\nconst COPY_SUCCESS_INTERVAL = 3000;\n\nconst messages = defineMessages({\n sidebarBg: {\n id: t('user.settings.custom_theme.sidebarBg'),\n defaultMessage: 'Sidebar BG',\n },\n sidebarText: {\n id: t('user.settings.custom_theme.sidebarText'),\n defaultMessage: 'Sidebar Text',\n },\n sidebarHeaderBg: {\n id: t('user.settings.custom_theme.sidebarHeaderBg'),\n defaultMessage: 'Sidebar Header BG',\n },\n sidebarTeamBarBg: {\n id: t('user.settings.custom_theme.sidebarTeamBarBg'),\n defaultMessage: 'Team Sidebar BG',\n },\n sidebarHeaderTextColor: {\n id: t('user.settings.custom_theme.sidebarHeaderTextColor'),\n defaultMessage: 'Sidebar Header Text',\n },\n sidebarUnreadText: {\n id: t('user.settings.custom_theme.sidebarUnreadText'),\n defaultMessage: 'Sidebar Unread Text',\n },\n sidebarTextHoverBg: {\n id: t('user.settings.custom_theme.sidebarTextHoverBg'),\n defaultMessage: 'Sidebar Text Hover BG',\n },\n sidebarTextActiveBorder: {\n id: t('user.settings.custom_theme.sidebarTextActiveBorder'),\n defaultMessage: 'Sidebar Text Active Border',\n },\n sidebarTextActiveColor: {\n id: t('user.settings.custom_theme.sidebarTextActiveColor'),\n defaultMessage: 'Sidebar Text Active Color',\n },\n onlineIndicator: {\n id: t('user.settings.custom_theme.onlineIndicator'),\n defaultMessage: 'Online Indicator',\n },\n awayIndicator: {\n id: t('user.settings.custom_theme.awayIndicator'),\n defaultMessage: 'Away Indicator',\n },\n dndIndicator: {\n id: t('user.settings.custom_theme.dndIndicator'),\n defaultMessage: 'Do Not Disturb Indicator',\n },\n mentionBg: {\n id: t('user.settings.custom_theme.mentionBg'),\n defaultMessage: 'Mention Jewel BG',\n },\n mentionColor: {\n id: t('user.settings.custom_theme.mentionColor'),\n defaultMessage: 'Mention Jewel Text',\n },\n centerChannelBg: {\n id: t('user.settings.custom_theme.centerChannelBg'),\n defaultMessage: 'Center Channel BG',\n },\n centerChannelColor: {\n id: t('user.settings.custom_theme.centerChannelColor'),\n defaultMessage: 'Center Channel Text',\n },\n newMessageSeparator: {\n id: t('user.settings.custom_theme.newMessageSeparator'),\n defaultMessage: 'New Message Separator',\n },\n linkColor: {\n id: t('user.settings.custom_theme.linkColor'),\n defaultMessage: 'Link Color',\n },\n buttonBg: {\n id: t('user.settings.custom_theme.buttonBg'),\n defaultMessage: 'Button BG',\n },\n buttonColor: {\n id: t('user.settings.custom_theme.buttonColor'),\n defaultMessage: 'Button Text',\n },\n errorTextColor: {\n id: t('user.settings.custom_theme.errorTextColor'),\n defaultMessage: 'Error Text Color',\n },\n mentionHighlightBg: {\n id: t('user.settings.custom_theme.mentionHighlightBg'),\n defaultMessage: 'Mention Highlight BG',\n },\n mentionHighlightLink: {\n id: t('user.settings.custom_theme.mentionHighlightLink'),\n defaultMessage: 'Mention Highlight Link',\n },\n codeTheme: {\n id: t('user.settings.custom_theme.codeTheme'),\n defaultMessage: 'Code Theme',\n },\n});\n\nexport default class CustomThemeChooser extends React.PureComponent {\n static propTypes = {\n theme: PropTypes.object.isRequired,\n updateTheme: PropTypes.func.isRequired,\n };\n\n constructor(props) {\n super(props);\n const copyTheme = this.setCopyTheme(this.props.theme);\n\n this.state = {\n copyTheme,\n };\n }\n\n handleColorChange = (settingId, color) => {\n const {updateTheme, theme} = this.props;\n if (theme[settingId] !== color) {\n const newTheme = {\n ...theme,\n type: 'custom',\n [settingId]: color,\n };\n\n // For backwards compatability\n if (settingId === 'mentionBg') {\n newTheme.mentionBj = color;\n }\n\n updateTheme(newTheme);\n\n const copyTheme = this.setCopyTheme(newTheme);\n\n this.setState({\n copyTheme,\n });\n }\n }\n\n setCopyTheme(theme) {\n const copyTheme = Object.assign({}, theme);\n delete copyTheme.type;\n delete copyTheme.image;\n\n return JSON.stringify(copyTheme);\n }\n\n pasteBoxChange = (e) => {\n let text = '';\n\n if (window.clipboardData && window.clipboardData.getData) { // IE\n text = window.clipboardData.getData('Text');\n } else {\n text = e.clipboardData.getData('Text');//e.clipboardData.getData('text/plain');\n }\n\n if (text.length === 0) {\n return;\n }\n\n let theme;\n try {\n theme = JSON.parse(text);\n } catch (err) {\n return;\n }\n\n theme = setThemeDefaults(theme);\n\n this.setState({\n copyTheme: JSON.stringify(theme),\n });\n\n theme.type = 'custom';\n this.props.updateTheme(theme);\n }\n\n onChangeHandle = (e) => {\n e.stopPropagation();\n }\n\n selectTheme = () => {\n const textarea = this.refs.textarea;\n textarea.focus();\n textarea.setSelectionRange(0, this.state.copyTheme.length);\n }\n\n toggleSidebarStyles = (e) => {\n e.preventDefault();\n\n this.refs.sidebarStylesHeader.classList.toggle('open');\n this.toggleSection(this.refs.sidebarStyles);\n }\n\n toggleCenterChannelStyles = (e) => {\n e.preventDefault();\n\n this.refs.centerChannelStylesHeader.classList.toggle('open');\n this.toggleSection(this.refs.centerChannelStyles);\n }\n\n toggleLinkAndButtonStyles = (e) => {\n e.preventDefault();\n\n this.refs.linkAndButtonStylesHeader.classList.toggle('open');\n this.toggleSection(this.refs.linkAndButtonStyles);\n }\n\n toggleSection(node) {\n node.classList.toggle('open');\n\n // set overflow after animation, so the colorchooser is fully shown\n node.ontransitionend = () => {\n if (node.classList.contains('open')) {\n node.style.overflowY = 'inherit';\n } else {\n node.style.overflowY = 'hidden';\n }\n };\n }\n\n onCodeThemeChange = (e) => {\n const theme = {\n ...this.props.theme,\n type: 'custom',\n codeTheme: e.target.value,\n };\n\n this.props.updateTheme(theme);\n }\n\n copyTheme = () => {\n this.selectTheme();\n document.execCommand('copy');\n this.showCopySuccess();\n }\n\n showCopySuccess = () => {\n const copySuccess = document.querySelector('.copy-theme-success');\n copySuccess.style.display = 'inline-block';\n\n setTimeout(() => {\n copySuccess.style.display = 'none';\n }, COPY_SUCCESS_INTERVAL);\n }\n\n render() {\n const theme = this.props.theme;\n\n const sidebarElements = [];\n const centerChannelElements = [];\n const linkAndButtonElements = [];\n Constants.THEME_ELEMENTS.forEach((element, index) => {\n if (element.id === 'codeTheme') {\n const codeThemeOptions = [];\n let codeThemeURL = '';\n\n element.themes.forEach((codeTheme, codeThemeIndex) => {\n if (codeTheme.id === theme[element.id]) {\n codeThemeURL = codeTheme.iconURL;\n }\n codeThemeOptions.push(\n <option\n key={'code-theme-key' + codeThemeIndex}\n value={codeTheme.id}\n >\n {codeTheme.uiName}\n </option>,\n );\n });\n\n var popoverContent = (\n <Popover\n popoverStyle='info'\n id='code-popover'\n className='code-popover'\n >\n <img\n width='200'\n alt={'code theme image'}\n src={codeThemeURL}\n />\n </Popover>\n );\n\n centerChannelElements.push(\n <div\n className='col-sm-6 form-group'\n key={'custom-theme-key' + index}\n >\n <label className='custom-label'>\n <FormattedMessage {...messages[element.id]}/>\n </label>\n <div\n className='input-group theme-group group--code dropdown'\n id={element.id}\n >\n <select\n id='codeThemeSelect'\n className='form-control'\n type='text'\n defaultValue={theme[element.id]}\n onChange={this.onCodeThemeChange}\n >\n {codeThemeOptions}\n </select>\n <OverlayTrigger\n placement='top'\n overlay={popoverContent}\n ref='headerOverlay'\n >\n <span className='input-group-addon'>\n <img\n alt={'code theme image'}\n src={codeThemeURL}\n />\n </span>\n </OverlayTrigger>\n </div>\n </div>,\n );\n } else if (element.group === 'centerChannelElements') {\n centerChannelElements.push(\n <div\n className='col-sm-6 form-group element'\n key={'custom-theme-key' + index}\n >\n <ColorChooser\n id={element.id}\n label={<FormattedMessage {...messages[element.id]}/>}\n value={theme[element.id]}\n onChange={this.handleColorChange}\n />\n </div>,\n );\n } else if (element.group === 'sidebarElements') {\n // Need to support old typo mentionBj element for mentionBg\n let color = theme[element.id];\n if (!color && element.id === 'mentionBg') {\n color = theme.mentionBj;\n }\n\n sidebarElements.push(\n <div\n className='col-sm-6 form-group element'\n key={'custom-theme-key' + index}\n >\n <ColorChooser\n id={element.id}\n label={<FormattedMessage {...messages[element.id]}/>}\n value={color}\n onChange={this.handleColorChange}\n />\n </div>,\n );\n } else {\n linkAndButtonElements.push(\n <div\n className='col-sm-6 form-group element'\n key={'custom-theme-key' + index}\n >\n <ColorChooser\n id={element.id}\n label={<FormattedMessage {...messages[element.id]}/>}\n value={theme[element.id]}\n onChange={this.handleColorChange}\n />\n </div>,\n );\n }\n });\n\n const pasteBox = (\n <div className='col-sm-12'>\n <label className='custom-label'>\n <FormattedMessage\n id='user.settings.custom_theme.copyPaste'\n defaultMessage='Copy to share or paste theme colors here:'\n />\n </label>\n <textarea\n ref='textarea'\n className='form-control'\n id='pasteBox'\n value={this.state.copyTheme}\n onCopy={this.showCopySuccess}\n onPaste={this.pasteBoxChange}\n onChange={this.onChangeHandle}\n onClick={this.selectTheme}\n />\n <div className='mt-3'>\n <button\n className='btn btn-link copy-theme-button'\n onClick={this.copyTheme}\n >\n <FormattedMessage\n id='user.settings.custom_theme.copyThemeColors'\n defaultMessage='Copy Theme Colors'\n />\n </button>\n <span\n className='alert alert-success copy-theme-success'\n role='alert'\n style={{display: 'none'}}\n >\n <FormattedMessage\n id='user.settings.custom_theme.copied'\n defaultMessage='✔ Copied'\n />\n </span>\n </div>\n </div>\n );\n\n return (\n <div className='appearance-section pt-2'>\n <div className='theme-elements row'>\n <div\n ref='sidebarStylesHeader'\n id='sidebarStyles'\n className='theme-elements__header'\n onClick={this.toggleSidebarStyles}\n >\n <FormattedMessage\n id='user.settings.custom_theme.sidebarTitle'\n defaultMessage='Sidebar Styles'\n />\n <div className='header__icon'>\n <LocalizedIcon\n className='fa fa-plus'\n title={{id: t('generic_icons.expand'), defaultMessage: 'Expand Icon'}}\n />\n <LocalizedIcon\n className='fa fa-minus'\n title={{id: t('generic_icons.collapse'), defaultMessage: 'Collapse Icon'}}\n />\n </div>\n </div>\n <div\n ref='sidebarStyles'\n className='theme-elements__body'\n >\n {sidebarElements}\n </div>\n </div>\n <div className='theme-elements row'>\n <div\n ref='centerChannelStylesHeader'\n id='centerChannelStyles'\n className='theme-elements__header'\n onClick={this.toggleCenterChannelStyles}\n >\n <FormattedMessage\n id='user.settings.custom_theme.centerChannelTitle'\n defaultMessage='Center Channel Styles'\n />\n <div className='header__icon'>\n <LocalizedIcon\n className='fa fa-plus'\n title={{id: t('generic_icons.expand'), defaultMessage: 'Expand Icon'}}\n />\n <LocalizedIcon\n className='fa fa-minus'\n title={{id: t('generic_icons.collapse'), defaultMessage: 'Collapse Icon'}}\n />\n </div>\n </div>\n <div\n ref='centerChannelStyles'\n id='centerChannelStyles'\n className='theme-elements__body'\n >\n {centerChannelElements}\n </div>\n </div>\n <div className='theme-elements row'>\n <div\n ref='linkAndButtonStylesHeader'\n id='linkAndButtonsStyles'\n className='theme-elements__header'\n onClick={this.toggleLinkAndButtonStyles}\n >\n <FormattedMessage\n id='user.settings.custom_theme.linkButtonTitle'\n defaultMessage='Link and Button Styles'\n />\n <div className='header__icon'>\n <LocalizedIcon\n className='fa fa-plus'\n title={{id: t('generic_icons.expand'), defaultMessage: 'Expand Icon'}}\n />\n <LocalizedIcon\n className='fa fa-minus'\n title={{id: t('generic_icons.collapse'), defaultMessage: 'Collapse Icon'}}\n />\n </div>\n </div>\n <div\n ref='linkAndButtonStyles'\n className='theme-elements__body'\n >\n {linkAndButtonElements}\n </div>\n </div>\n <div className='row mt-3'>\n {pasteBox}\n </div>\n </div>\n );\n }\n}\n/* eslint-enable react/no-string-refs */\n","// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.\n// See LICENSE.txt for license information.\n\n/* eslint-disable react/jsx-max-props-per-line */\n\nimport React from 'react';\n\ntype ThemeThumbnailProps = {\n themeName: string;\n themeKey: string;\n sidebarBg: string;\n sidebarText: string;\n sidebarUnreadText: string;\n onlineIndicator: string;\n awayIndicator: string;\n dndIndicator: string;\n centerChannelColor: string;\n centerChannelBg: string;\n newMessageSeparator: string;\n buttonBg: string;\n}\n\nfunction ThemeThumbnail({\n themeName,\n themeKey,\n sidebarBg = '#174AB5',\n sidebarText = '#86A1D9',\n sidebarUnreadText = 'white',\n onlineIndicator = '#3DB887',\n awayIndicator = '#FFBC1F',\n dndIndicator = '#D24B4E',\n centerChannelColor = '#E0E1E3',\n centerChannelBg = 'white',\n newMessageSeparator = '#1C58D9',\n buttonBg = '#15B7B7',\n}: ThemeThumbnailProps): JSX.Element {\n return (\n <svg width='112' height='86' viewBox='0 0 112 86' fill='none' xmlns='http://www.w3.org/2000/svg' aria-labelledby={`${themeKey}-theme-icon`} role='img'>\n <title id={`${themeKey}-theme-icon`}>{`${themeName} theme icon`}</title>\n <rect style={{fill: centerChannelBg}} x='0' y='0' width='112' height='86'/>\n <g>\n <rect style={{fill: centerChannelBg}} x='50' y='-1' width='63' height='88'/>\n <g>\n <rect style={{fill: centerChannelColor}} x='55' y='75' width='52' height='6' rx='3'/>\n <rect style={{fill: centerChannelBg}} x='56' y='76' width='50' height='4' rx='2'/>\n </g>\n <rect style={{fill: buttonBg}} x='71' y='65' width='22' height='5' rx='2.5'/>\n <rect style={{fill: newMessageSeparator}} x='50' y='32' width='62' height='1'/>\n <g style={{fill: centerChannelColor}}>\n <rect x='55' y='5' width='52' height='4' rx='2'/>\n <rect x='55' y='14' width='52' height='4' rx='2'/>\n <rect x='55' y='23' width='52' height='4' rx='2'/>\n <rect x='55' y='38' width='52' height='4' rx='2'/>\n <rect x='55' y='47' width='52' height='4' rx='2'/>\n <rect x='55' y='56' width='52' height='4' rx='2'/>\n </g>\n </g>\n <g>\n <rect style={{fill: sidebarBg}} x='-1' y='-1' width='51' height='88'/>\n <g style={{fill: sidebarText}}>\n <circle cx='7' cy='61' r='2'/>\n <circle cx='7' cy='70' r='2'/>\n <circle cx='7' cy='43' r='2'/>\n <circle cx='7' cy='34' r='2'/>\n <circle cx='7' cy='16' r='2'/>\n <circle cx='7' cy='7' r='2'/>\n <rect x='11' y='5' width='28' height='4' rx='2'/>\n <rect x='11' y='14' width='28' height='4' rx='2'/>\n <rect x='11' y='32' width='28' height='4' rx='2'/>\n <rect x='11' y='41' width='28' height='4' rx='2'/>\n <rect x='11' y='50' width='28' height='4' rx='2'/>\n <rect x='11' y='59' width='28' height='4' rx='2'/>\n <rect x='11' y='68' width='28' height='4' rx='2'/>\n <rect x='11' y='77' width='28' height='4' rx='2'/>\n </g>\n <circle style={{fill: dndIndicator}} cx='7' cy='79' r='2'/>\n <circle style={{fill: awayIndicator}} cx='7' cy='52' r='2'/>\n <circle style={{fill: onlineIndicator}} cx='7' cy='25' r='2'/>\n <g style={{fill: sidebarUnreadText}}>\n <circle cx='43' cy='25' r='2'/>\n <rect x='11' y='23' width='28' height='4' rx='2'/>\n </g>\n </g>\n </svg>\n );\n}\n\nexport default ThemeThumbnail;\n","// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.\n// See LICENSE.txt for license information.\n\nimport PropTypes from 'prop-types';\nimport React from 'react';\n\nimport {Preferences} from 'mattermost-redux/constants';\nimport * as Utils from 'utils/utils.jsx';\nimport {changeOpacity} from 'mattermost-redux/utils/theme_utils';\n\nimport ThemeThumbnail from '../theme_thumbnail';\n\nexport default class PremadeThemeChooser extends React.PureComponent {\n render() {\n const theme = this.props.theme;\n\n const premadeThemes = [];\n const allowedThemes = this.props.allowedThemes;\n const hasAllowedThemes = allowedThemes.length > 1 || (allowedThemes[0] && allowedThemes[0].trim().length > 0);\n\n for (const k in Preferences.THEMES) {\n if (Preferences.THEMES.hasOwnProperty(k)) {\n if (hasAllowedThemes && allowedThemes.indexOf(k) < 0) {\n continue;\n }\n\n const premadeTheme = Object.assign({}, Preferences.THEMES[k]);\n\n let activeClass = '';\n if (premadeTheme.type === theme.type) {\n activeClass = 'active';\n }\n\n premadeThemes.push(\n <div\n className='col-xs-6 col-sm-3 premade-themes'\n key={'premade-theme-key' + k}\n >\n <div\n id={`premadeTheme${premadeTheme.type.replace(' ', '')}`}\n className={activeClass}\n onClick={() => this.props.updateTheme(premadeTheme)}\n >\n <label>\n <ThemeThumbnail\n themeKey={k}\n themeName={premadeTheme.type}\n sidebarBg={premadeTheme.sidebarBg}\n sidebarText={changeOpacity(premadeTheme.sidebarText, 0.48)}\n sidebarUnreadText={premadeTheme.sidebarUnreadText}\n onlineIndicator={premadeTheme.onlineIndicator}\n awayIndicator={premadeTheme.awayIndicator}\n dndIndicator={premadeTheme.dndIndicator}\n centerChannelColor={changeOpacity(premadeTheme.centerChannelColor, 0.16)}\n centerChannelBg={premadeTheme.centerChannelBg}\n newMessageSeparator={premadeTheme.newMessageSeparator}\n buttonBg={premadeTheme.buttonBg}\n />\n <div className='theme-label'>{Utils.toTitleCase(premadeTheme.type)}</div>\n </label>\n </div>\n </div>,\n );\n }\n }\n\n return (\n <div className='row appearance-section'>\n <div className='clearfix'>\n {premadeThemes}\n </div>\n </div>\n );\n }\n}\n\nPremadeThemeChooser.propTypes = {\n theme: PropTypes.object.isRequired,\n updateTheme: PropTypes.func.isRequired,\n allowedThemes: PropTypes.arrayOf(PropTypes.string),\n};\n\nPremadeThemeChooser.defaultProps = {\n allowedThemes: [],\n};\n","// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.\n// See LICENSE.txt for license information.\n\nimport {connect} from 'react-redux';\n\nimport {getConfig} from 'mattermost-redux/selectors/entities/general';\n\nimport PremadeThemeChooser from './premade_theme_chooser.jsx';\n\nfunction mapStateToProps(state) {\n const config = getConfig(state);\n\n const allowedThemes = (config.AllowedThemes && config.AllowedThemes.split(',')) || [];\n\n return {\n allowedThemes,\n };\n}\n\nexport default connect(mapStateToProps)(PremadeThemeChooser);\n","// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.\n// See LICENSE.txt for license information.\n/* eslint-disable react/no-string-refs */\n\nimport $ from 'jquery';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport ReactDOM from 'react-dom';\nimport {FormattedMessage} from 'react-intl';\n\nimport {ActionTypes, Constants} from 'utils/constants';\nimport * as Utils from 'utils/utils.jsx';\nimport AppDispatcher from 'dispatcher/app_dispatcher.jsx';\nimport SettingItemMax from 'components/setting_item_max.jsx';\nimport SettingItemMin from 'components/setting_item_min';\n\nimport CustomThemeChooser from './custom_theme_chooser.jsx';\nimport PremadeThemeChooser from './premade_theme_chooser';\n\nexport default class ThemeSetting extends React.PureComponent {\n static propTypes = {\n actions: PropTypes.shape({\n saveTheme: PropTypes.func.isRequired,\n deleteTeamSpecificThemes: PropTypes.func.isRequired,\n }).isRequired,\n currentTeamId: PropTypes.string.isRequired,\n theme: PropTypes.object,\n selected: PropTypes.bool.isRequired,\n updateSection: PropTypes.func.isRequired,\n setRequireConfirm: PropTypes.func.isRequired,\n setEnforceFocus: PropTypes.func.isRequired,\n allowCustomThemes: PropTypes.bool,\n };\n\n constructor(props) {\n super(props);\n\n this.state = {\n ...this.getStateFromProps(props),\n isSaving: false,\n };\n\n this.originalTheme = Object.assign({}, this.state.theme);\n }\n\n componentDidMount() {\n if (this.props.selected) {\n $(ReactDOM.findDOMNode(this.refs[this.state.theme])).addClass('active-border'); // eslint-disable-line jquery/no-class\n }\n }\n\n componentDidUpdate(prevProps) {\n if (prevProps.selected && !this.props.selected) {\n this.resetFields();\n }\n\n if (this.props.selected) {\n $('.color-btn').removeClass('active-border'); // eslint-disable-line jquery/no-class\n $(ReactDOM.findDOMNode(this.refs[this.state.theme])).addClass('active-border'); // eslint-disable-line jquery/no-class\n }\n }\n\n componentWillUnmount() {\n if (this.props.selected) {\n Utils.applyTheme(this.props.theme);\n }\n }\n\n getStateFromProps(props = this.props) {\n const theme = {...props.theme};\n if (!theme.codeTheme) {\n theme.codeTheme = Constants.DEFAULT_CODE_THEME;\n }\n\n return {\n theme,\n type: theme.type || 'premade',\n showAllTeamsCheckbox: props.showAllTeamsCheckbox,\n applyToAllTeams: props.applyToAllTeams,\n };\n }\n\n submitTheme = async () => {\n const teamId = this.state.applyToAllTeams ? '' : this.props.currentTeamId;\n\n this.setState({isSaving: true});\n\n await this.props.actions.saveTheme(teamId, this.state.theme);\n\n if (this.state.applyToAllTeams) {\n await this.props.actions.deleteTeamSpecificThemes();\n }\n\n this.props.setRequireConfirm(false);\n this.originalTheme = Object.assign({}, this.state.theme);\n this.props.updateSection('');\n this.setState({isSaving: false});\n };\n\n updateTheme = (theme) => {\n let themeChanged = this.state.theme.length === theme.length;\n if (!themeChanged) {\n for (const field in theme) {\n if (theme.hasOwnProperty(field)) {\n if (this.state.theme[field] !== theme[field]) {\n themeChanged = true;\n break;\n }\n }\n }\n }\n\n this.props.setRequireConfirm(themeChanged);\n\n this.setState({theme});\n Utils.applyTheme(theme);\n };\n\n updateType(type) {\n this.setState({type});\n }\n\n resetFields = () => {\n const state = this.getStateFromProps();\n state.serverError = null;\n this.setState(state);\n\n Utils.applyTheme(state.theme);\n\n this.props.setRequireConfirm(false);\n };\n\n handleImportModal = () => {\n AppDispatcher.handleViewAction({\n type: ActionTypes.TOGGLE_IMPORT_THEME_MODAL,\n value: true,\n callback: this.updateTheme,\n });\n\n this.props.setEnforceFocus(false);\n };\n\n handleUpdateSection = (section) => {\n this.props.updateSection(section);\n };\n\n render() {\n let serverError;\n if (this.state.serverError) {\n serverError = this.state.serverError;\n }\n\n const displayCustom = this.state.type === 'custom';\n\n let custom;\n let premade;\n if (displayCustom && this.props.allowCustomThemes) {\n custom = (\n <div key='customThemeChooser'>\n <CustomThemeChooser\n theme={this.state.theme}\n updateTheme={this.updateTheme}\n />\n </div>\n );\n } else {\n premade = (\n <div key='premadeThemeChooser'>\n <br/>\n <PremadeThemeChooser\n theme={this.state.theme}\n updateTheme={this.updateTheme}\n />\n </div>\n );\n }\n\n let themeUI;\n if (this.props.selected) {\n const inputs = [];\n\n if (this.props.allowCustomThemes) {\n inputs.push(\n <div\n className='radio'\n key='premadeThemeColorLabel'\n >\n <label>\n <input\n id='standardThemes'\n type='radio'\n name='theme'\n checked={!displayCustom}\n onChange={this.updateType.bind(this, 'premade')}\n />\n <FormattedMessage\n id='user.settings.display.theme.themeColors'\n defaultMessage='Theme Colors'\n />\n </label>\n <br/>\n </div>,\n );\n }\n\n inputs.push(premade);\n\n if (this.props.allowCustomThemes) {\n inputs.push(\n <div\n className='radio'\n key='customThemeColorLabel'\n >\n <label>\n <input\n id='customThemes'\n type='radio'\n name='theme'\n checked={displayCustom}\n onChange={this.updateType.bind(this, 'custom')}\n />\n <FormattedMessage\n id='user.settings.display.theme.customTheme'\n defaultMessage='Custom Theme'\n />\n </label>\n </div>,\n );\n\n inputs.push(custom);\n\n inputs.push(\n <div key='otherThemes'>\n <br/>\n <a\n id='otherThemes'\n href='http://docs.mattermost.com/help/settings/theme-colors.html#custom-theme-examples'\n target='_blank'\n rel='noopener noreferrer'\n >\n <FormattedMessage\n id='user.settings.display.theme.otherThemes'\n defaultMessage='See other themes'\n />\n </a>\n </div>,\n );\n\n inputs.push(\n <div\n key='importSlackThemeButton'\n className='pt-2'\n >\n <button\n id='slackImportTheme'\n className='theme style--none color--link'\n onClick={this.handleImportModal}\n >\n <FormattedMessage\n id='user.settings.display.theme.import'\n defaultMessage='Import theme colors from Slack'\n />\n </button>\n </div>,\n );\n }\n\n let allTeamsCheckbox = null;\n if (this.state.showAllTeamsCheckbox) {\n allTeamsCheckbox = (\n <div className='checkbox user-settings__submit-checkbox'>\n <label>\n <input\n id='applyThemeToAllTeams'\n type='checkbox'\n checked={this.state.applyToAllTeams}\n onChange={(e) => this.setState({applyToAllTeams: e.target.checked})}\n />\n <FormattedMessage\n id='user.settings.display.theme.applyToAllTeams'\n defaultMessage='Apply new theme to all my teams'\n />\n </label>\n </div>\n );\n }\n\n themeUI = (\n <SettingItemMax\n inputs={inputs}\n submitExtra={allTeamsCheckbox}\n submit={this.submitTheme}\n disableEnterSubmit={true}\n saving={this.state.isSaving}\n server_error={serverError}\n width='full'\n updateSection={this.handleUpdateSection}\n />\n );\n } else {\n themeUI = (\n <SettingItemMin\n title={\n <FormattedMessage\n id='user.settings.display.theme.title'\n defaultMessage='Theme'\n />\n }\n describe={\n <FormattedMessage\n id='user.settings.display.theme.describe'\n defaultMessage='Open to manage your theme'\n />\n }\n section={'theme'}\n updateSection={this.handleUpdateSection}\n />\n );\n }\n\n return themeUI;\n }\n}\n/* eslint-enable react/no-string-refs */\n","// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.\n// See LICENSE.txt for license information.\n\nimport {connect} from 'react-redux';\nimport {bindActionCreators} from 'redux';\n\nimport {getTheme, makeGetCategory} from 'mattermost-redux/selectors/entities/preferences';\nimport {getCurrentTeamId, getMyTeamsCount} from 'mattermost-redux/selectors/entities/teams';\n\nimport {saveTheme, deleteTeamSpecificThemes} from 'mattermost-redux/actions/preferences';\n\nimport {Preferences} from 'utils/constants';\n\nimport UserSettingsTheme from './user_settings_theme.jsx';\n\nfunction makeMapStateToProps() {\n const getThemeCategory = makeGetCategory();\n\n return (state) => {\n return {\n currentTeamId: getCurrentTeamId(state),\n theme: getTheme(state),\n applyToAllTeams: getThemeCategory(state, Preferences.CATEGORY_THEME).length <= 1,\n showAllTeamsCheckbox: getMyTeamsCount(state) > 1,\n };\n };\n}\n\nfunction mapDispatchToProps(dispatch) {\n return {\n actions: bindActionCreators({\n saveTheme,\n deleteTeamSpecificThemes,\n }, dispatch),\n };\n}\n\nexport default connect(makeMapStateToProps, mapDispatchToProps)(UserSettingsTheme);\n","// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.\n// See LICENSE.txt for license information.\n\nimport React from 'react';\nimport {FormattedMessage} from 'react-intl';\nimport ReactSelect, {ValueType} from 'react-select';\nimport {Timezone} from 'timezones.json';\n\nimport {UserProfile} from 'mattermost-redux/types/users';\nimport {ActionResult} from 'mattermost-redux/types/actions';\n\nimport SettingItemMax from 'components/setting_item_max.jsx';\nimport {getBrowserTimezone} from 'utils/timezone';\nimport {getTimezoneLabel} from 'mattermost-redux/utils/timezone_utils';\n\ntype Actions = {\n updateMe: (user: UserProfile) => Promise<ActionResult>;\n}\n\ntype Props = {\n user: UserProfile;\n updateSection: (section: string) => void;\n useAutomaticTimezone: boolean;\n automaticTimezone: string;\n manualTimezone: string;\n timezones: Timezone[];\n timezoneLabel: string;\n actions: Actions;\n}\ntype SelectedOption = {\n value: string;\n label: string;\n}\n\ntype State = {\n useAutomaticTimezone: boolean;\n automaticTimezone: string;\n manualTimezone: string;\n isSaving: boolean;\n serverError?: string;\n openMenu: boolean;\n selectedOption: SelectedOption;\n}\n\nexport default class ManageTimezones extends React.PureComponent<Props, State> {\n constructor(props: Props) {\n super(props);\n this.state = {\n useAutomaticTimezone: props.useAutomaticTimezone,\n automaticTimezone: props.automaticTimezone,\n manualTimezone: props.manualTimezone,\n isSaving: false,\n openMenu: false,\n selectedOption: {label: props.timezoneLabel, value: props.useAutomaticTimezone ? props.automaticTimezone : props.manualTimezone},\n };\n }\n\n onChange = (selectedOption: ValueType<SelectedOption>) => {\n if (selectedOption && 'value' in selectedOption) {\n this.setState({\n manualTimezone: selectedOption.value,\n selectedOption,\n });\n }\n }\n\n timezoneNotChanged = () => {\n const {\n useAutomaticTimezone,\n automaticTimezone,\n manualTimezone,\n } = this.state;\n\n const {\n useAutomaticTimezone: oldUseAutomaticTimezone,\n automaticTimezone: oldAutomaticTimezone,\n manualTimezone: oldManualTimezone,\n } = this.props;\n\n return (\n useAutomaticTimezone === oldUseAutomaticTimezone &&\n automaticTimezone === oldAutomaticTimezone &&\n manualTimezone === oldManualTimezone\n );\n };\n\n changeTimezone = () => {\n if (this.timezoneNotChanged()) {\n this.props.updateSection('');\n return;\n }\n\n this.submitUser();\n };\n\n submitUser = () => {\n const {user, actions} = this.props;\n const {useAutomaticTimezone, automaticTimezone, manualTimezone} = this.state;\n\n const timezone = {\n useAutomaticTimezone: useAutomaticTimezone.toString(),\n automaticTimezone,\n manualTimezone,\n };\n\n const updatedUser = {\n ...user,\n timezone,\n };\n\n actions.updateMe(updatedUser).\n then((res) => {\n if ('data' in res) {\n this.props.updateSection('');\n } else if ('error' in res) {\n const {error} = res;\n let serverError;\n if (error instanceof Error) {\n serverError = error.message;\n } else {\n serverError = error as string;\n }\n this.setState({serverError, isSaving: false});\n }\n });\n };\n\n handleAutomaticTimezone = (e: React.ChangeEvent<HTMLInputElement>) => {\n const useAutomaticTimezone = e.target.checked;\n let automaticTimezone = '';\n let timezoneLabel: string;\n let selectedOptionValue: string;\n\n if (useAutomaticTimezone) {\n automaticTimezone = getBrowserTimezone();\n timezoneLabel = getTimezoneLabel(this.props.timezones, automaticTimezone);\n selectedOptionValue = automaticTimezone;\n } else {\n timezoneLabel = getTimezoneLabel(this.props.timezones, this.props.manualTimezone || getBrowserTimezone());\n selectedOptionValue = this.props.manualTimezone || getBrowserTimezone();\n if (!this.props.manualTimezone) {\n this.setState({\n manualTimezone: getBrowserTimezone(),\n });\n }\n }\n\n this.setState({\n useAutomaticTimezone,\n automaticTimezone,\n selectedOption: {label: timezoneLabel, value: selectedOptionValue},\n });\n };\n\n handleManualTimezone = (e: React.ChangeEvent<HTMLSelectElement>) => {\n this.setState({manualTimezone: e.target.value});\n };\n render() {\n const {timezones} = this.props;\n const {useAutomaticTimezone} = this.state;\n\n const timeOptions = this.props.timezones.map((timeObject) => {\n return {\n value: timeObject.utc[0],\n label: timeObject.text,\n };\n });\n let serverError;\n if (this.state.serverError) {\n serverError = <label className='has-error'>{this.state.serverError}</label>;\n }\n\n const inputs = [];\n const reactStyles = {\n\n menuPortal: (provided: React.CSSProperties) => ({\n ...provided,\n zIndex: 9999,\n }),\n\n };\n\n const noTimezonesFromServer = timezones.length === 0;\n const automaticTimezoneInput = (\n <div className='checkbox'>\n <label>\n <input\n id='automaticTimezoneInput'\n type='checkbox'\n checked={useAutomaticTimezone}\n onChange={this.handleAutomaticTimezone}\n disabled={noTimezonesFromServer}\n />\n <FormattedMessage\n id='user.settings.timezones.automatic'\n defaultMessage='Automatic'\n />\n\n </label>\n </div>\n );\n\n const manualTimezoneInput = (\n <div\n className='pt-2'\n >\n <ReactSelect\n className='react-select react-select-top'\n classNamePrefix='react-select'\n id='displayTimezone'\n menuPortalTarget={document.body}\n styles={reactStyles}\n options={timeOptions}\n clearable={false}\n onChange={this.onChange}\n value={this.state.selectedOption}\n aria-labelledby='changeInterfaceTimezoneLabel'\n isDisabled={useAutomaticTimezone}\n />\n {serverError}\n </div>\n );\n\n inputs.push(automaticTimezoneInput);\n\n inputs.push(manualTimezoneInput);\n\n inputs.push(\n <div>\n <br/>\n <FormattedMessage\n id='user.settings.timezones.promote'\n defaultMessage='Select the time zone used for timestamps in the user interface and email notifications.'\n />\n </div>,\n );\n\n return (\n <SettingItemMax\n title={\n <FormattedMessage\n id='user.settings.display.timezone'\n defaultMessage='Timezone'\n />\n }\n containerStyle='timezone-container'\n width='medium'\n submit={this.changeTimezone}\n saving={this.state.isSaving}\n inputs={inputs}\n updateSection={this.props.updateSection}\n />\n );\n }\n}\n\n","// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.\n// See LICENSE.txt for license information.\nimport {connect} from 'react-redux';\nimport {ActionCreatorsMapObject, bindActionCreators, Dispatch} from 'redux';\n\nimport timezones from 'timezones.json';\n\nimport {updateMe} from 'mattermost-redux/actions/users';\nimport {ActionFunc, ActionResult} from 'mattermost-redux/types/actions';\nimport {UserProfile} from 'mattermost-redux/types/users';\nimport {GlobalState} from 'mattermost-redux/types/store';\nimport {getTimezoneLabel} from 'mattermost-redux/selectors/entities/timezone';\n\nimport {getCurrentUserId} from 'mattermost-redux/selectors/entities/users';\n\nimport ManageTimezones from './manage_timezones';\n\ntype Actions = {\n updateMe: (user: UserProfile) => Promise<ActionResult>;\n}\n\nfunction mapDispatchToProps(dispatch: Dispatch) {\n return {\n actions: bindActionCreators<ActionCreatorsMapObject<ActionFunc>, Actions>({\n updateMe,\n }, dispatch)};\n}\nfunction mapStateToProps(state: GlobalState) {\n const currentUserId = getCurrentUserId(state);\n const timezoneLabel = getTimezoneLabel(state, currentUserId);\n return {\n timezones,\n timezoneLabel,\n };\n}\nexport default connect(mapStateToProps, mapDispatchToProps)(ManageTimezones);\n\n","// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.\n// See LICENSE.txt for license information.\n\nimport React from 'react';\nimport {FormattedMessage} from 'react-intl';\nimport ReactSelect, {ValueType} from 'react-select';\n\nimport {ActionResult} from 'mattermost-redux/types/actions';\nimport {UserProfile} from 'mattermost-redux/types/users';\n\nimport * as I18n from 'i18n/i18n.jsx';\nimport SettingItemMax from 'components/setting_item_max.jsx';\nimport FormattedMarkdownMessage from 'components/formatted_markdown_message.jsx';\nimport {isKeyPressed} from 'utils/utils.jsx';\nimport Constants from 'utils/constants';\n\ntype Actions = {\n updateMe: (user: UserProfile) => Promise<ActionResult>;\n};\n\ntype Props = {\n user: UserProfile;\n locale: string;\n updateSection: (section: string) => void;\n actions: Actions;\n};\n\ntype SelectedOption = {\n value: string;\n label: string;\n}\n\ntype State = {\n isSaving: boolean;\n openMenu: boolean;\n locale: string;\n serverError?: string;\n selectedOption: SelectedOption;\n};\n\nexport default class ManageLanguage extends React.PureComponent<Props, State> {\n reactSelectContainer: React.RefObject<HTMLDivElement>;\n constructor(props: Props) {\n super(props);\n const locales: any = I18n.getLanguages();\n const userLocale = props.locale;\n const selectedOption = {\n value: locales[userLocale].value,\n label: locales[userLocale].name,\n };\n this.reactSelectContainer = React.createRef();\n\n this.state = {\n locale: props.locale,\n selectedOption,\n isSaving: false,\n openMenu: false,\n };\n }\n\n componentDidMount() {\n const reactSelectContainer = this.reactSelectContainer.current;\n if (reactSelectContainer) {\n reactSelectContainer.addEventListener(\n 'keydown',\n this.handleContainerKeyDown,\n );\n }\n }\n\n componentWillUnmount() {\n if (this.reactSelectContainer.current) {\n this.reactSelectContainer.current.removeEventListener(\n 'keydown',\n this.handleContainerKeyDown,\n );\n }\n }\n\n handleContainerKeyDown = (e: KeyboardEvent) => {\n const modalBody = document.querySelector('.modal-body');\n if (isKeyPressed(e, Constants.KeyCodes.ESCAPE) && this.state.openMenu) {\n modalBody?.classList.remove('no-scroll');\n this.setState({openMenu: false});\n e.stopPropagation();\n }\n };\n\n handleKeyDown = (e: React.KeyboardEvent) => {\n const modalBody = document.querySelector('.modal-body');\n if (isKeyPressed(e, Constants.KeyCodes.ENTER)) {\n modalBody?.classList.add('no-scroll');\n this.setState({openMenu: true});\n }\n };\n\n setLanguage = (selectedOption: ValueType<SelectedOption>) => {\n if (selectedOption && 'value' in selectedOption) {\n this.setState({\n locale: selectedOption.value,\n selectedOption,\n });\n }\n };\n\n changeLanguage = () => {\n if (this.props.user.locale === this.state.locale) {\n this.props.updateSection('');\n } else {\n this.submitUser({\n ...this.props.user,\n locale: this.state.locale,\n });\n }\n };\n\n submitUser = (user: UserProfile) => {\n this.setState({isSaving: true});\n\n this.props.actions.updateMe(user).then((res) => {\n if ('data' in res) {\n // Do nothing since changing the locale essentially refreshes the page\n } else if ('error' in res) {\n let serverError;\n const {error} = res;\n if (error instanceof Error) {\n serverError = error.message;\n } else {\n serverError = error;\n }\n this.setState({serverError, isSaving: false});\n }\n });\n };\n\n handleMenuClose = () => {\n const modalBody = document.querySelector('.modal-body');\n if (modalBody) {\n modalBody.classList.remove('no-scroll');\n }\n this.setState({openMenu: false});\n };\n\n handleMenuOpen = () => {\n const modalBody = document.querySelector('.modal-body');\n if (modalBody) {\n modalBody.classList.add('no-scroll');\n }\n this.setState({openMenu: true});\n };\n\n render() {\n let serverError;\n if (this.state.serverError) {\n serverError = (\n <label className='has-error'>{this.state.serverError}</label>\n );\n }\n\n const options: SelectedOption[] = [];\n const locales: any = I18n.getLanguages();\n\n const languages = Object.keys(locales).\n map((l) => {\n return {\n value: locales[l].value as string,\n name: locales[l].name,\n order: locales[l].order,\n };\n }).\n sort((a, b) => a.order - b.order);\n\n languages.forEach((lang) => {\n options.push({value: lang.value, label: lang.name});\n });\n\n const reactStyles = {\n menuPortal: (provided: React.CSSProperties) => ({\n ...provided,\n zIndex: 9999,\n }),\n };\n\n const input = (\n <div key='changeLanguage'>\n <br/>\n <label\n className='control-label'\n id='changeInterfaceLanguageLabel'\n >\n <FormattedMessage\n id='user.settings.languages.change'\n defaultMessage='Change interface language'\n />\n </label>\n <div\n ref={this.reactSelectContainer}\n className='pt-2'\n >\n <ReactSelect\n className='react-select react-select-top'\n classNamePrefix='react-select'\n id='displayLanguage'\n menuIsOpen={this.state.openMenu}\n menuPortalTarget={document.body}\n styles={reactStyles}\n options={options}\n clearable={false}\n onChange={this.setLanguage}\n onKeyDown={this.handleKeyDown}\n value={this.state.selectedOption}\n onMenuClose={this.handleMenuClose}\n onMenuOpen={this.handleMenuOpen}\n aria-labelledby='changeInterfaceLanguageLabel'\n />\n {serverError}\n </div>\n <div>\n <br/>\n <FormattedMarkdownMessage\n id='user.settings.languages.promote'\n defaultMessage='Select which language Mattermost displays in the user interface.\\n \\nWould you like to help with translations? Join the [Mattermost Translation Server](!http://translate.mattermost.com/) to contribute.'\n />\n </div>\n </div>\n );\n\n return (\n <SettingItemMax\n title={\n <FormattedMessage\n id='user.settings.display.language'\n defaultMessage='Language'\n />\n }\n width='medium'\n submit={this.changeLanguage}\n saving={this.state.isSaving}\n inputs={[input]}\n updateSection={this.props.updateSection}\n />\n );\n }\n}\n","// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.\n// See LICENSE.txt for license information.\nimport {connect} from 'react-redux';\nimport {ActionCreatorsMapObject, bindActionCreators, Dispatch} from 'redux';\n\nimport {updateMe} from 'mattermost-redux/actions/users';\nimport {UserProfile} from 'mattermost-redux/types/users';\nimport {ActionFunc, ActionResult} from 'mattermost-redux/types/actions';\n\nimport ManageLanguages from './manage_languages';\n\ntype Actions = {\n updateMe: (user: UserProfile) => Promise<ActionResult>;\n}\n\nfunction mapDispatchToProps(dispatch: Dispatch) {\n return {\n actions: bindActionCreators<ActionCreatorsMapObject<ActionFunc>, Actions>({\n updateMe,\n }, dispatch)};\n}\n\nexport default connect(null, mapDispatchToProps)(ManageLanguages);\n","// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.\n// See LICENSE.txt for license information.\n/* eslint-disable react/no-string-refs */\n\nimport React from 'react';\n\nimport {FormattedMessage} from 'react-intl';\n\nimport {Timezone} from 'timezones.json';\n\nimport {PreferenceType} from 'mattermost-redux/types/preferences';\nimport {UserProfile, UserTimezone} from 'mattermost-redux/types/users';\n\nimport {trackEvent} from 'actions/telemetry_actions';\n\nimport Constants from 'utils/constants';\nimport * as Utils from 'utils/utils.jsx';\nimport {getBrowserTimezone} from 'utils/timezone.jsx';\n\nimport * as I18n from 'i18n/i18n.jsx';\nimport {t} from 'utils/i18n';\n\nimport FormattedMarkdownMessage from 'components/formatted_markdown_message.jsx';\nimport SettingItemMax from 'components/setting_item_max.jsx';\nimport SettingItemMin from 'components/setting_item_min';\nimport ThemeSetting from 'components/user_settings/display/user_settings_theme';\nimport BackIcon from 'components/widgets/icons/fa_back_icon';\n\nimport ManageTimezones from './manage_timezones';\nimport ManageLanguages from './manage_languages';\n\nconst Preferences = Constants.Preferences;\n\nfunction getDisplayStateFromProps(props: Props) {\n return {\n militaryTime: props.militaryTime,\n teammateNameDisplay: props.teammateNameDisplay,\n availabilityStatusOnPosts: props.availabilityStatusOnPosts,\n channelDisplayMode: props.channelDisplayMode,\n messageDisplay: props.messageDisplay,\n collapseDisplay: props.collapseDisplay,\n collapsedReplyThreads: props.collapsedReplyThreads,\n linkPreviewDisplay: props.linkPreviewDisplay,\n };\n}\n\ntype Option = {\n value: string;\n radionButtonText: {\n id: string;\n message: string;\n moreId?: string;\n moreMessage?: string;\n };\n}\n\ntype SectionProps ={\n section: string;\n display: string;\n defaultDisplay: string;\n value: string;\n title: {\n id: string;\n message: string;\n };\n firstOption: Option;\n secondOption: Option;\n thirdOption?: Option;\n description: {\n id: string;\n message: string;\n };\n disabled?: boolean;\n}\n\ntype Props = {\n user: UserProfile;\n updateSection: (section: string) => void;\n activeSection?: string;\n closeModal?: () => void;\n collapseModal?: () => void;\n setRequireConfirm?: () => void;\n setEnforceFocus?: () => void;\n timezones: Timezone[];\n userTimezone: UserTimezone;\n allowCustomThemes: boolean;\n enableLinkPreviews: boolean;\n defaultClientLocale: string;\n enableThemeSelection: boolean;\n configTeammateNameDisplay: string;\n currentUserTimezone: string;\n enableTimezone: boolean;\n shouldAutoUpdateTimezone: boolean;\n lockTeammateNameDisplay: boolean;\n militaryTime: string;\n teammateNameDisplay: string;\n availabilityStatusOnPosts: string;\n channelDisplayMode: string;\n messageDisplay: string;\n collapseDisplay: string;\n collapsedReplyThreads: string;\n collapsedReplyThreadsAllowUserPreference: boolean;\n linkPreviewDisplay: string;\n timezoneLabel: string;\n actions: {\n savePreferences: (userId: string, preferences: PreferenceType[]) => void;\n autoUpdateTimezone: (deviceTimezone: string) => void;\n };\n}\n\ntype State = {\n [key: string]: any;\n isSaving: boolean;\n militaryTime: string;\n teammateNameDisplay: string;\n availabilityStatusOnPosts: string;\n channelDisplayMode: string;\n messageDisplay: string;\n collapseDisplay: string;\n collapsedReplyThreads: string;\n linkPreviewDisplay: string;\n handleSubmit?: () => void;\n serverError?: string;\n}\n\nexport default class UserSettingsDisplay extends React.PureComponent<Props, State> {\n public prevSections: {\n theme: string;\n\n clock: string;\n linkpreview: string;\n message_display: string;\n channel_display_mode: string;\n languages: string;\n };\n\n constructor(props: Props) {\n super(props);\n\n this.state = {\n ...getDisplayStateFromProps(props),\n isSaving: false,\n };\n\n this.prevSections = {\n theme: 'dummySectionName', // dummy value that should never match any section name\n clock: 'theme',\n linkpreview: 'clock',\n message_display: 'linkpreview',\n channel_display_mode: 'message_display',\n languages: 'channel_display_mode',\n };\n }\n\n componentDidMount() {\n const {actions, enableTimezone, shouldAutoUpdateTimezone} = this.props;\n\n if (enableTimezone && shouldAutoUpdateTimezone) {\n actions.autoUpdateTimezone(getBrowserTimezone());\n }\n }\n\n componentDidUpdate(prevProps: Props) {\n if (this.props.teammateNameDisplay !== prevProps.teammateNameDisplay) {\n this.updateState();\n }\n }\n\n trackChangeIfNecessary(preference: PreferenceType, oldValue: any): void {\n const props = {\n field: 'display.' + preference.name,\n value: preference.value,\n };\n\n if (preference.value !== oldValue) {\n trackEvent('settings', 'user_settings_update', props);\n }\n }\n\n handleSubmit = async () => {\n const userId = this.props.user.id;\n\n const timePreference = {\n user_id: userId,\n category: Preferences.CATEGORY_DISPLAY_SETTINGS,\n name: Preferences.USE_MILITARY_TIME,\n value: this.state.militaryTime,\n };\n const availabilityStatusOnPostsPreference = {\n user_id: userId,\n category: Preferences.CATEGORY_DISPLAY_SETTINGS,\n name: Preferences.AVAILABILITY_STATUS_ON_POSTS,\n value: this.state.availabilityStatusOnPosts,\n };\n const teammateNameDisplayPreference = {\n user_id: userId,\n category: Preferences.CATEGORY_DISPLAY_SETTINGS,\n name: Preferences.NAME_NAME_FORMAT,\n value: this.state.teammateNameDisplay,\n };\n const channelDisplayModePreference = {\n user_id: userId,\n category: Preferences.CATEGORY_DISPLAY_SETTINGS,\n name: Preferences.CHANNEL_DISPLAY_MODE,\n value: this.state.channelDisplayMode,\n };\n const messageDisplayPreference = {\n user_id: userId,\n category: Preferences.CATEGORY_DISPLAY_SETTINGS,\n name: Preferences.MESSAGE_DISPLAY,\n value: this.state.messageDisplay,\n };\n const collapseDisplayPreference = {\n user_id: userId,\n category: Preferences.CATEGORY_DISPLAY_SETTINGS,\n name: Preferences.COLLAPSE_DISPLAY,\n value: this.state.collapseDisplay,\n };\n const collapsedReplyThreadsPreference = {\n user_id: userId,\n category: Preferences.CATEGORY_DISPLAY_SETTINGS,\n name: Preferences.COLLAPSED_REPLY_THREADS,\n value: this.state.collapsedReplyThreads,\n };\n const linkPreviewDisplayPreference = {\n user_id: userId,\n category: Preferences.CATEGORY_DISPLAY_SETTINGS,\n name: Preferences.LINK_PREVIEW_DISPLAY,\n value: this.state.linkPreviewDisplay,\n };\n\n this.setState({isSaving: true});\n\n const preferences = [\n timePreference,\n channelDisplayModePreference,\n messageDisplayPreference,\n collapsedReplyThreadsPreference,\n collapseDisplayPreference,\n linkPreviewDisplayPreference,\n teammateNameDisplayPreference,\n availabilityStatusOnPostsPreference,\n ];\n\n this.trackChangeIfNecessary(collapsedReplyThreadsPreference, this.props.collapsedReplyThreads);\n\n await this.props.actions.savePreferences(userId, preferences);\n\n this.updateSection('');\n }\n\n handleClockRadio = (militaryTime: string) => {\n this.setState({militaryTime});\n }\n\n handleTeammateNameDisplayRadio = (teammateNameDisplay: string) => {\n this.setState({teammateNameDisplay});\n }\n\n handleAvailabilityStatusRadio = (availabilityStatusOnPosts: string) => {\n this.setState({availabilityStatusOnPosts});\n }\n\n handleChannelDisplayModeRadio(channelDisplayMode: string) {\n this.setState({channelDisplayMode});\n }\n\n handlemessageDisplayRadio(messageDisplay: string) {\n this.setState({messageDisplay});\n }\n\n handleCollapseRadio(collapseDisplay: string) {\n this.setState({collapseDisplay});\n }\n\n handleCollapseReplyThreadsRadio(collapsedReplyThreads: string) {\n this.setState({collapsedReplyThreads});\n }\n\n handleLinkPreviewRadio(linkPreviewDisplay: string) {\n this.setState({linkPreviewDisplay});\n }\n\n handleOnChange(display: {[key: string]: any}) {\n this.setState({...display});\n }\n\n updateSection = (section: string) => {\n this.updateState();\n this.props.updateSection(section);\n }\n\n updateState = () => {\n const newState = getDisplayStateFromProps(this.props);\n if (!Utils.areObjectsEqual(newState, this.state)) {\n this.setState(newState);\n }\n\n this.setState({isSaving: false});\n }\n\n createSection(props: SectionProps) {\n const {\n section,\n display,\n value,\n title,\n firstOption,\n secondOption,\n thirdOption,\n description,\n disabled,\n } = props;\n let extraInfo = null;\n let submit: (() => Promise<void>) | null = this.handleSubmit;\n\n const firstMessage = (\n <FormattedMessage\n id={firstOption.radionButtonText.id}\n defaultMessage={firstOption.radionButtonText.message}\n />\n );\n\n let moreColon;\n let firstMessageMore;\n if (firstOption.radionButtonText.moreId) {\n moreColon = ': ';\n firstMessageMore = (\n <span className='font-weight--normal'>\n <FormattedMessage\n id={firstOption.radionButtonText.moreId}\n defaultMessage={firstOption.radionButtonText.moreMessage}\n />\n </span>\n );\n }\n\n const secondMessage = (\n <FormattedMessage\n id={secondOption.radionButtonText.id}\n defaultMessage={secondOption.radionButtonText.message}\n />\n );\n\n let secondMessageMore;\n if (secondOption.radionButtonText.moreId) {\n secondMessageMore = (\n <span className='font-weight--normal'>\n <FormattedMessage\n id={secondOption.radionButtonText.moreId}\n defaultMessage={secondOption.radionButtonText.moreMessage}\n />\n </span>\n );\n }\n\n let thirdMessage;\n if (thirdOption) {\n thirdMessage = (\n <FormattedMessage\n id={thirdOption.radionButtonText.id}\n defaultMessage={thirdOption.radionButtonText.message}\n />\n );\n }\n\n const messageTitle = (\n <FormattedMessage\n id={title.id}\n defaultMessage={title.message}\n />\n );\n\n const messageDesc = (\n <FormattedMarkdownMessage\n id={description.id}\n defaultMessage={description.message}\n />\n );\n\n if (this.props.activeSection === section) {\n const format = [false, false, false];\n if (value === firstOption.value) {\n format[0] = true;\n } else if (value === secondOption.value) {\n format[1] = true;\n } else {\n format[2] = true;\n }\n\n const name = section + 'Format';\n const key = section + 'UserDisplay';\n\n const firstDisplay = {\n [display]: firstOption.value,\n };\n\n const secondDisplay = {\n [display]: secondOption.value,\n };\n\n let thirdSection;\n if (thirdOption && thirdMessage) {\n const thirdDisplay = {\n [display]: thirdOption.value,\n };\n\n thirdSection = (\n <div className='radio'>\n <label>\n <input\n id={name + 'C'}\n type='radio'\n name={name}\n checked={format[2]}\n onChange={() => this.handleOnChange(thirdDisplay)}\n />\n {thirdMessage}\n </label>\n <br/>\n </div>\n );\n }\n\n let inputs = [\n <fieldset key={key}>\n <legend className='form-legend hidden-label'>\n {messageTitle}\n </legend>\n <div className='radio'>\n <label>\n <input\n id={name + 'A'}\n type='radio'\n name={name}\n checked={format[0]}\n onChange={() => this.handleOnChange(firstDisplay)}\n />\n {firstMessage}\n {moreColon}\n {firstMessageMore}\n </label>\n <br/>\n </div>\n <div className='radio'>\n <label>\n <input\n id={name + 'B'}\n type='radio'\n name={name}\n checked={format[1]}\n onChange={() => this.handleOnChange(secondDisplay)}\n />\n {secondMessage}\n {moreColon}\n {secondMessageMore}\n </label>\n <br/>\n </div>\n {thirdSection}\n <div>\n <br/>\n {messageDesc}\n </div>\n </fieldset>,\n ];\n\n if (display === 'teammateNameDisplay' && disabled) {\n extraInfo = (\n <span>\n <FormattedMessage\n id='user.settings.display.teammateNameDisplay'\n defaultMessage='This field is handled through your System Administrator. If you want to change it, you need to do so through your System Administrator.'\n />\n </span>\n );\n submit = null;\n inputs = [];\n }\n return (\n <div>\n <SettingItemMax\n title={messageTitle}\n inputs={inputs}\n submit={submit}\n saving={this.state.isSaving}\n server_error={this.state.serverError}\n updateSection={this.updateSection}\n extraInfo={extraInfo}\n />\n <div className='divider-dark'/>\n </div>\n );\n }\n\n let describe;\n if (value === firstOption.value) {\n describe = firstMessage;\n } else if (value === secondOption.value) {\n describe = secondMessage;\n } else {\n describe = thirdMessage;\n }\n\n return (\n <div>\n <SettingItemMin\n title={messageTitle}\n describe={describe}\n section={section}\n updateSection={this.updateSection}\n />\n <div className='divider-dark'/>\n </div>\n );\n }\n\n render() {\n const collapseSection = this.createSection({\n section: 'collapse',\n display: 'collapseDisplay',\n value: this.state.collapseDisplay,\n defaultDisplay: 'false',\n title: {\n id: t('user.settings.display.collapseDisplay'),\n message: 'Default Appearance of Image Previews',\n },\n firstOption: {\n value: 'false',\n radionButtonText: {\n id: t('user.settings.display.collapseOn'),\n message: 'On',\n },\n },\n secondOption: {\n value: 'true',\n radionButtonText: {\n id: t('user.settings.display.collapseOff'),\n message: 'Off',\n },\n },\n description: {\n id: t('user.settings.display.collapseDesc'),\n message: 'Set whether previews of image links and image attachment thumbnails show as expanded or collapsed by default. This setting can also be controlled using the slash commands /expand and /collapse.',\n },\n });\n\n let linkPreviewSection = null;\n\n if (this.props.enableLinkPreviews) {\n linkPreviewSection = this.createSection({\n section: 'linkpreview',\n display: 'linkPreviewDisplay',\n value: this.state.linkPreviewDisplay,\n defaultDisplay: 'true',\n title: {\n id: t('user.settings.display.linkPreviewDisplay'),\n message: 'Website Link Previews',\n },\n firstOption: {\n value: 'true',\n radionButtonText: {\n id: t('user.settings.display.linkPreviewOn'),\n message: 'On',\n },\n },\n secondOption: {\n value: 'false',\n radionButtonText: {\n id: t('user.settings.display.linkPreviewOff'),\n message: 'Off',\n },\n },\n description: {\n id: t('user.settings.display.linkPreviewDesc'),\n message: 'When available, the first web link in a message will show a preview of the website content below the message.',\n },\n });\n this.prevSections.message_display = 'linkpreview';\n } else {\n this.prevSections.message_display = this.prevSections.linkpreview;\n }\n\n const clockSection = this.createSection({\n section: 'clock',\n display: 'militaryTime',\n value: this.state.militaryTime,\n defaultDisplay: 'false',\n title: {\n id: t('user.settings.display.clockDisplay'),\n message: 'Clock Display',\n },\n firstOption: {\n value: 'false',\n radionButtonText: {\n id: t('user.settings.display.normalClock'),\n message: '12-hour clock (example: 4:00 PM)',\n },\n },\n secondOption: {\n value: 'true',\n radionButtonText: {\n id: t('user.settings.display.militaryClock'),\n message: '24-hour clock (example: 16:00)',\n },\n },\n description: {\n id: t('user.settings.display.preferTime'),\n message: 'Select how you prefer time displayed.',\n },\n });\n\n const teammateNameDisplaySection = this.createSection({\n section: Preferences.NAME_NAME_FORMAT,\n display: 'teammateNameDisplay',\n value: this.props.lockTeammateNameDisplay ? this.props.configTeammateNameDisplay : this.state.teammateNameDisplay,\n defaultDisplay: this.props.configTeammateNameDisplay,\n title: {\n id: t('user.settings.display.teammateNameDisplayTitle'),\n message: 'Teammate Name Display',\n },\n firstOption: {\n value: Constants.TEAMMATE_NAME_DISPLAY.SHOW_USERNAME,\n radionButtonText: {\n id: t('user.settings.display.teammateNameDisplayUsername'),\n message: 'Show username',\n },\n },\n secondOption: {\n value: Constants.TEAMMATE_NAME_DISPLAY.SHOW_NICKNAME_FULLNAME,\n radionButtonText: {\n id: t('user.settings.display.teammateNameDisplayNicknameFullname'),\n message: 'Show nickname if one exists, otherwise show first and last name',\n },\n },\n thirdOption: {\n value: Constants.TEAMMATE_NAME_DISPLAY.SHOW_FULLNAME,\n radionButtonText: {\n id: t('user.settings.display.teammateNameDisplayFullname'),\n message: 'Show first and last name',\n },\n },\n description: {\n id: t('user.settings.display.teammateNameDisplayDescription'),\n message: 'Set how to display other user\\'s names in posts and the Direct Messages list.',\n },\n disabled: this.props.lockTeammateNameDisplay,\n });\n\n const availabilityStatusOnPostsSection = this.createSection({\n section: 'availabilityStatus',\n display: 'availabilityStatusOnPosts',\n value: this.state.availabilityStatusOnPosts,\n defaultDisplay: 'true',\n title: {\n id: t('user.settings.display.availabilityStatusOnPostsTitle'),\n message: 'Show user availability on posts',\n },\n firstOption: {\n value: 'true',\n radionButtonText: {\n id: t('user.settings.sidebar.on'),\n message: 'On',\n },\n },\n secondOption: {\n value: 'false',\n radionButtonText: {\n id: t('user.settings.sidebar.off'),\n message: 'Off',\n },\n },\n description: {\n id: t('user.settings.display.availabilityStatusOnPostsDescription'),\n message: 'When enabled, online availability is displayed on profile images in the message list.',\n },\n });\n\n let timezoneSelection;\n if (this.props.enableTimezone && !this.props.shouldAutoUpdateTimezone) {\n const userTimezone = this.props.userTimezone;\n if (this.props.activeSection === 'timezone') {\n timezoneSelection = (\n <div>\n <ManageTimezones\n user={this.props.user}\n useAutomaticTimezone={Boolean(userTimezone.useAutomaticTimezone)}\n automaticTimezone={userTimezone.automaticTimezone}\n manualTimezone={userTimezone.manualTimezone}\n updateSection={this.updateSection}\n />\n <div className='divider-dark'/>\n </div>\n );\n } else {\n timezoneSelection = (\n <div>\n <SettingItemMin\n title={\n <FormattedMessage\n id='user.settings.display.timezone'\n defaultMessage='Timezone'\n />\n }\n describe={this.props.timezoneLabel}\n section={'timezone'}\n updateSection={this.updateSection}\n />\n <div className='divider-dark'/>\n </div>\n );\n }\n }\n\n const messageDisplaySection = this.createSection({\n section: Preferences.MESSAGE_DISPLAY,\n display: 'messageDisplay',\n value: this.state.messageDisplay,\n defaultDisplay: Preferences.MESSAGE_DISPLAY_CLEAN,\n title: {\n id: t('user.settings.display.messageDisplayTitle'),\n message: 'Message Display',\n },\n firstOption: {\n value: Preferences.MESSAGE_DISPLAY_CLEAN,\n radionButtonText: {\n id: t('user.settings.display.messageDisplayClean'),\n message: 'Standard',\n moreId: t('user.settings.display.messageDisplayCleanDes'),\n moreMessage: 'Easy to scan and read.',\n },\n },\n secondOption: {\n value: Preferences.MESSAGE_DISPLAY_COMPACT,\n radionButtonText: {\n id: t('user.settings.display.messageDisplayCompact'),\n message: 'Compact',\n moreId: t('user.settings.display.messageDisplayCompactDes'),\n moreMessage: 'Fit as many messages on the screen as we can.',\n },\n },\n description: {\n id: t('user.settings.display.messageDisplayDescription'),\n message: 'Select how messages in a channel should be displayed.',\n },\n });\n\n let collapsedReplyThreads;\n\n if (this.props.collapsedReplyThreadsAllowUserPreference) {\n collapsedReplyThreads = this.createSection({\n section: Preferences.COLLAPSED_REPLY_THREADS,\n display: 'collapsedReplyThreads',\n value: this.state.collapsedReplyThreads,\n defaultDisplay: Preferences.COLLAPSED_REPLY_THREADS_FALLBACK_DEFAULT,\n title: {\n id: t('user.settings.display.collapsedReplyThreadsTitle'),\n message: 'Collapsed Reply Threads (Beta)',\n },\n firstOption: {\n value: Preferences.COLLAPSED_REPLY_THREADS_ON,\n radionButtonText: {\n id: t('user.settings.display.collapsedReplyThreadsOn'),\n message: 'On',\n },\n },\n secondOption: {\n value: Preferences.COLLAPSED_REPLY_THREADS_OFF,\n radionButtonText: {\n id: t('user.settings.display.collapsedReplyThreadsOff'),\n message: 'Off',\n },\n },\n description: {\n id: t('user.settings.display.collapsedReplyThreadsDescription'),\n message: 'When enabled, reply messages are not shown in the channel and you\\'ll be notified about threads you\\'re following in the \"Threads\" view.\\nPlease review our [documentation for known issues](!https://docs.mattermost.com/help/messaging/organizing-conversations.html) and help provide feedback in our [community channel](!https://community-daily.mattermost.com/core/channels/folded-reply-threads).',\n },\n });\n }\n\n const channelDisplayModeSection = this.createSection({\n section: Preferences.CHANNEL_DISPLAY_MODE,\n display: 'channelDisplayMode',\n value: this.state.channelDisplayMode,\n defaultDisplay: Preferences.CHANNEL_DISPLAY_MODE_FULL_SCREEN,\n title: {\n id: t('user.settings.display.channelDisplayTitle'),\n message: 'Channel Display',\n },\n firstOption: {\n value: Preferences.CHANNEL_DISPLAY_MODE_FULL_SCREEN,\n radionButtonText: {\n id: t('user.settings.display.fullScreen'),\n message: 'Full width',\n },\n },\n secondOption: {\n value: Preferences.CHANNEL_DISPLAY_MODE_CENTERED,\n radionButtonText: {\n id: t('user.settings.display.fixedWidthCentered'),\n message: 'Fixed width, centered',\n },\n },\n description: {\n id: t('user.settings.display.channeldisplaymode'),\n message: 'Select the width of the center channel.',\n },\n });\n\n let languagesSection;\n let userLocale = this.props.user.locale;\n if (this.props.activeSection === 'languages') {\n if (!I18n.isLanguageAvailable(userLocale)) {\n userLocale = this.props.defaultClientLocale;\n }\n languagesSection = (\n <div>\n <ManageLanguages\n user={this.props.user}\n locale={userLocale}\n updateSection={this.updateSection}\n />\n <div className='divider-dark'/>\n </div>\n );\n } else {\n let locale;\n if (I18n.isLanguageAvailable(userLocale)) {\n locale = I18n.getLanguageInfo(userLocale).name;\n } else {\n locale = I18n.getLanguageInfo(this.props.defaultClientLocale).name;\n }\n\n languagesSection = (\n <div>\n <SettingItemMin\n title={\n <FormattedMessage\n id='user.settings.display.language'\n defaultMessage='Language'\n />\n }\n describe={locale}\n section={'languages'}\n updateSection={this.updateSection}\n />\n <div className='divider-dark'/>\n </div>\n );\n }\n\n if (Object.keys(I18n.getLanguages()).length === 1) {\n languagesSection = null;\n }\n\n let themeSection;\n if (this.props.enableThemeSelection) {\n themeSection = (\n <div>\n <ThemeSetting\n selected={this.props.activeSection === 'theme'}\n updateSection={this.updateSection}\n setRequireConfirm={this.props.setRequireConfirm}\n setEnforceFocus={this.props.setEnforceFocus}\n allowCustomThemes={this.props.allowCustomThemes}\n />\n <div className='divider-dark'/>\n </div>\n );\n }\n\n return (\n <div id='displaySettings'>\n <div className='modal-header'>\n <button\n id='closeButton'\n type='button'\n className='close'\n data-dismiss='modal'\n aria-label='Close'\n onClick={this.props.closeModal}\n >\n <span aria-hidden='true'>{'×'}</span>\n </button>\n <h4\n className='modal-title'\n ref='title'\n >\n <div className='modal-back'>\n <span onClick={this.props.collapseModal}>\n <BackIcon/>\n </span>\n </div>\n <FormattedMessage\n id='user.settings.display.title'\n defaultMessage='Display Settings'\n />\n </h4>\n </div>\n <div className='user-settings'>\n <h3\n id='displaySettingsTitle'\n className='tab-header'\n >\n <FormattedMessage\n id='user.settings.display.title'\n defaultMessage='Display Settings'\n />\n </h3>\n <div className='divider-dark first'/>\n {themeSection}\n {clockSection}\n {teammateNameDisplaySection}\n {availabilityStatusOnPostsSection}\n {timezoneSelection}\n {linkPreviewSection}\n {collapseSection}\n {messageDisplaySection}\n {collapsedReplyThreads}\n {channelDisplayModeSection}\n {languagesSection}\n </div>\n </div>\n );\n }\n}\n/* eslint-enable react/no-string-refs */\n","// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.\n// See LICENSE.txt for license information.\n\nimport {connect} from 'react-redux';\n\nimport {bindActionCreators, Dispatch} from 'redux';\n\nimport timezones from 'timezones.json';\n\nimport {GenericAction} from 'mattermost-redux/types/actions';\n\nimport {savePreferences} from 'mattermost-redux/actions/preferences';\nimport {autoUpdateTimezone} from 'mattermost-redux/actions/timezone';\nimport {getConfig, getLicense} from 'mattermost-redux/selectors/entities/general';\nimport {getCurrentUserId} from 'mattermost-redux/selectors/entities/users';\nimport {get, isCollapsedThreadsAllowed, getCollapsedThreadsPreference} from 'mattermost-redux/selectors/entities/preferences';\nimport {getTimezoneLabel, getUserTimezone} from 'mattermost-redux/selectors/entities/timezone';\nimport {getUserCurrentTimezone} from 'mattermost-redux/utils/timezone_utils';\n\nimport {GlobalState} from 'types/store';\nimport {Preferences} from 'utils/constants';\n\nimport UserSettingsDisplay from './user_settings_display';\n\nfunction mapStateToProps(state: GlobalState) {\n const config = getConfig(state);\n const currentUserId = getCurrentUserId(state);\n const userTimezone = getUserTimezone(state, currentUserId);\n const automaticTimezoneNotSet = userTimezone && userTimezone.useAutomaticTimezone && !userTimezone.automaticTimezone;\n const shouldAutoUpdateTimezone = !userTimezone || automaticTimezoneNotSet;\n const timezoneLabel = getTimezoneLabel(state, currentUserId);\n const allowCustomThemes = config.AllowCustomThemes === 'true';\n const enableLinkPreviews = config.EnableLinkPreviews === 'true';\n const defaultClientLocale = config.DefaultClientLocale as string;\n const enableThemeSelection = config.EnableThemeSelection === 'true';\n const enableTimezone = config.ExperimentalTimezone === 'true';\n const lockTeammateNameDisplay = getLicense(state).LockTeammateNameDisplay === 'true' && config.LockTeammateNameDisplay === 'true';\n const configTeammateNameDisplay = config.TeammateNameDisplay as string;\n\n return {\n lockTeammateNameDisplay,\n allowCustomThemes,\n configTeammateNameDisplay,\n enableLinkPreviews,\n defaultClientLocale,\n enableThemeSelection,\n enableTimezone,\n timezones,\n timezoneLabel,\n userTimezone,\n shouldAutoUpdateTimezone,\n currentUserTimezone: getUserCurrentTimezone(userTimezone) as string,\n availabilityStatusOnPosts: get(state, Preferences.CATEGORY_DISPLAY_SETTINGS, Preferences.AVAILABILITY_STATUS_ON_POSTS, Preferences.AVAILABILITY_STATUS_ON_POSTS_DEFAULT),\n militaryTime: get(state, Preferences.CATEGORY_DISPLAY_SETTINGS, Preferences.USE_MILITARY_TIME, Preferences.USE_MILITARY_TIME_DEFAULT),\n teammateNameDisplay: get(state, Preferences.CATEGORY_DISPLAY_SETTINGS, Preferences.NAME_NAME_FORMAT, configTeammateNameDisplay),\n channelDisplayMode: get(state, Preferences.CATEGORY_DISPLAY_SETTINGS, Preferences.CHANNEL_DISPLAY_MODE, Preferences.CHANNEL_DISPLAY_MODE_DEFAULT),\n messageDisplay: get(state, Preferences.CATEGORY_DISPLAY_SETTINGS, Preferences.MESSAGE_DISPLAY, Preferences.MESSAGE_DISPLAY_DEFAULT),\n collapseDisplay: get(state, Preferences.CATEGORY_DISPLAY_SETTINGS, Preferences.COLLAPSE_DISPLAY, Preferences.COLLAPSE_DISPLAY_DEFAULT),\n collapsedReplyThreadsAllowUserPreference: isCollapsedThreadsAllowed(state) && getConfig(state).CollapsedThreads as string !== 'always_on',\n collapsedReplyThreads: getCollapsedThreadsPreference(state),\n linkPreviewDisplay: get(state, Preferences.CATEGORY_DISPLAY_SETTINGS, Preferences.LINK_PREVIEW_DISPLAY, Preferences.LINK_PREVIEW_DISPLAY_DEFAULT),\n };\n}\n\nfunction mapDispatchToProps(dispatch: Dispatch<GenericAction>) {\n return {\n actions: bindActionCreators({\n autoUpdateTimezone,\n savePreferences,\n }, dispatch),\n };\n}\n\nexport default connect(mapStateToProps, mapDispatchToProps)(UserSettingsDisplay);\n","// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.\n// See LICENSE.txt for license information.\n/* eslint-disable react/no-string-refs */\n\nimport React from 'react';\nimport {defineMessages, FormattedDate, FormattedMessage, injectIntl, IntlShape} from 'react-intl';\n\nimport {isEmail} from 'mattermost-redux/utils/helpers';\nimport {UserProfile} from 'mattermost-redux/types/users';\n\nimport {trackEvent} from 'actions/telemetry_actions.jsx';\nimport * as Utils from 'utils/utils.jsx';\nimport {t} from 'utils/i18n';\n\nimport SettingItemMax from 'components/setting_item_max.jsx';\nimport SettingItemMin from 'components/setting_item_min';\nimport SettingPicture from 'components/setting_picture.jsx';\nimport LoadingWrapper from 'components/widgets/loading/loading_wrapper';\nimport {AnnouncementBarMessages, AnnouncementBarTypes, AcceptedProfileImageTypes, Constants, ValidationErrors} from 'utils/constants';\n\nconst holders = defineMessages({\n usernameReserved: {\n id: t('user.settings.general.usernameReserved'),\n defaultMessage: 'This username is reserved, please choose a new one.',\n },\n usernameRestrictions: {\n id: t('user.settings.general.usernameRestrictions'),\n defaultMessage: \"Username must begin with a letter, and contain between {min} to {max} lowercase characters made up of numbers, letters, and the symbols '.', '-', and '_'.\",\n },\n validEmail: {\n id: t('user.settings.general.validEmail'),\n defaultMessage: 'Please enter a valid email address.',\n },\n emailMatch: {\n id: t('user.settings.general.emailMatch'),\n defaultMessage: 'The new emails you entered do not match.',\n },\n incorrectPassword: {\n id: t('user.settings.general.incorrectPassword'),\n defaultMessage: 'Your password is incorrect.',\n },\n emptyPassword: {\n id: t('user.settings.general.emptyPassword'),\n defaultMessage: 'Please enter your current password.',\n },\n validImage: {\n id: t('user.settings.general.validImage'),\n defaultMessage: 'Only BMP, JPG, JPEG, or PNG images may be used for profile pictures',\n },\n imageTooLarge: {\n id: t('user.settings.general.imageTooLarge'),\n defaultMessage: 'Unable to upload profile image. File is too large.',\n },\n uploadImage: {\n id: t('user.settings.general.uploadImage'),\n defaultMessage: \"Click 'Edit' to upload an image.\",\n },\n uploadImageMobile: {\n id: t('user.settings.general.mobile.uploadImage'),\n defaultMessage: 'Click to upload an image',\n },\n fullName: {\n id: t('user.settings.general.fullName'),\n defaultMessage: 'Full Name',\n },\n nickname: {\n id: t('user.settings.general.nickname'),\n defaultMessage: 'Nickname',\n },\n username: {\n id: t('user.settings.general.username'),\n defaultMessage: 'Username',\n },\n profilePicture: {\n id: t('user.settings.general.profilePicture'),\n defaultMessage: 'Profile Picture',\n },\n close: {\n id: t('user.settings.general.close'),\n defaultMessage: 'Close',\n },\n position: {\n id: t('user.settings.general.position'),\n defaultMessage: 'Position',\n },\n});\n\nexport type Props = {\n intl: IntlShape;\n user: UserProfile;\n updateSection: (section: string) => void;\n updateTab: (notifications: string) => void;\n activeSection?: string;\n closeModal: () => void;\n collapseModal: () => void;\n maxFileSize: number;\n actions: {\n logError: ({message, type}: {message: any; type: string}, status: boolean) => void;\n clearErrors: () => void;\n getMe: () => void;\n updateMe: (user: UserProfile) => Promise<{\n data: boolean;\n error?: {\n server_error_id: string;\n message: string;\n };\n }>;\n sendVerificationEmail: (email: string) => Promise<{\n data: boolean;\n error?: {\n err: string;\n };\n }>;\n setDefaultProfileImage: (id: string) => void;\n uploadProfileImage: (id: string, file: File) => Promise<{\n data: boolean;\n error?: {\n message: string;\n };\n }>;\n };\n requireEmailVerification?: boolean;\n ldapFirstNameAttributeSet?: boolean;\n ldapLastNameAttributeSet?: boolean;\n samlFirstNameAttributeSet?: boolean;\n samlLastNameAttributeSet?: boolean;\n ldapNicknameAttributeSet?: boolean;\n samlNicknameAttributeSet?: boolean;\n ldapPositionAttributeSet?: boolean;\n samlPositionAttributeSet?: boolean;\n ldapPictureAttributeSet?: boolean;\n}\n\ntype State = {\n username: string;\n firstName: string;\n lastName: string;\n nickname: string;\n position: string;\n originalEmail: string;\n email: string;\n confirmEmail: string;\n currentPassword: string;\n pictureFile: File | null;\n loadingPicture: boolean;\n sectionIsSaving: boolean;\n showSpinner: boolean;\n resendStatus?: string;\n clientError?: string | null;\n serverError?: string | {server_error_id: string; message: string};\n emailError?: string;\n}\n\nexport class UserSettingsGeneralTab extends React.Component<Props, State> {\n public submitActive = false;\n\n constructor(props: Props) {\n super(props);\n\n this.state = this.setupInitialState(props);\n }\n\n handleEmailResend = (email: string) => {\n this.setState({resendStatus: 'sending', showSpinner: true});\n this.props.actions.sendVerificationEmail(email).then(({data, error: err}) => {\n if (data) {\n this.setState({resendStatus: 'success'});\n } else if (err) {\n this.setState({resendStatus: 'failure'});\n }\n });\n }\n\n createEmailResendLink = (email: string) => {\n return (\n <span className='resend-verification-wrapper'>\n <LoadingWrapper\n loading={this.state.showSpinner}\n text={Utils.localizeMessage('user.settings.general.sending', 'Sending')}\n >\n <a\n onClick={() => {\n this.handleEmailResend(email);\n setTimeout(() => {\n this.setState({\n showSpinner: false,\n });\n }, 500);\n }}\n >\n <FormattedMessage\n id='user.settings.general.sendAgain'\n defaultMessage='Send again'\n />\n </a>\n </LoadingWrapper>\n </span>\n );\n }\n\n submitUsername = () => {\n const user = Object.assign({}, this.props.user);\n const username = this.state.username.trim().toLowerCase();\n\n const {formatMessage} = this.props.intl;\n const usernameError = Utils.isValidUsername(username);\n if (usernameError) {\n let errObj;\n if (usernameError.id === ValidationErrors.RESERVED_NAME) {\n errObj = {clientError: formatMessage(holders.usernameReserved), serverError: ''};\n } else {\n errObj = {clientError: formatMessage(holders.usernameRestrictions, {min: Constants.MIN_USERNAME_LENGTH, max: Constants.MAX_USERNAME_LENGTH}), serverError: ''};\n }\n this.setState(errObj);\n return;\n }\n\n if (user.username === username) {\n this.updateSection('');\n return;\n }\n\n user.username = username;\n\n trackEvent('settings', 'user_settings_update', {field: 'username'});\n\n this.submitUser(user, false);\n }\n\n submitNickname = () => {\n const user = Object.assign({}, this.props.user);\n const nickname = this.state.nickname.trim();\n\n if (user.nickname === nickname) {\n this.updateSection('');\n return;\n }\n\n user.nickname = nickname;\n\n trackEvent('settings', 'user_settings_update', {field: 'nickname'});\n\n this.submitUser(user, false);\n }\n\n submitName = () => {\n const user = Object.assign({}, this.props.user);\n const firstName = this.state.firstName.trim();\n const lastName = this.state.lastName.trim();\n\n if (user.first_name === firstName && user.last_name === lastName) {\n this.updateSection('');\n return;\n }\n\n user.first_name = firstName;\n user.last_name = lastName;\n\n trackEvent('settings', 'user_settings_update', {field: 'fullname'});\n\n this.submitUser(user, false);\n }\n\n submitEmail = () => {\n const user = Object.assign({}, this.props.user);\n const email = this.state.email.trim().toLowerCase();\n const confirmEmail = this.state.confirmEmail.trim().toLowerCase();\n const currentPassword = this.state.currentPassword;\n\n const {formatMessage} = this.props.intl;\n\n if (email === user.email && (confirmEmail === '' || confirmEmail === user.email)) {\n this.updateSection('');\n return;\n }\n\n if (email === '' || !isEmail(email)) {\n this.setState({emailError: formatMessage(holders.validEmail), clientError: '', serverError: ''});\n return;\n }\n\n if (email !== confirmEmail) {\n this.setState({emailError: formatMessage(holders.emailMatch), clientError: '', serverError: ''});\n return;\n }\n\n if (currentPassword === '') {\n this.setState({emailError: formatMessage(holders.emptyPassword), clientError: '', serverError: ''});\n return;\n }\n\n user.email = email;\n user.password = currentPassword;\n trackEvent('settings', 'user_settings_update', {field: 'email'});\n this.submitUser(user, true);\n }\n\n submitUser = (user: UserProfile, emailUpdated: boolean) => {\n const {formatMessage} = this.props.intl;\n this.setState({sectionIsSaving: true});\n\n this.props.actions.updateMe(user).\n then(({data, error: err}) => {\n if (data) {\n this.updateSection('');\n this.props.actions.getMe();\n const verificationEnabled = this.props.requireEmailVerification && emailUpdated;\n if (verificationEnabled) {\n this.props.actions.clearErrors();\n this.props.actions.logError({\n message: AnnouncementBarMessages.EMAIL_VERIFICATION_REQUIRED,\n type: AnnouncementBarTypes.SUCCESS,\n }, true);\n }\n } else if (err) {\n let serverError;\n if (err.server_error_id &&\n err.server_error_id === 'api.user.check_user_password.invalid.app_error') {\n serverError = formatMessage(holders.incorrectPassword);\n } else if (err.message) {\n serverError = err.message;\n } else {\n serverError = err;\n }\n this.setState({serverError, emailError: '', clientError: '', sectionIsSaving: false});\n }\n });\n }\n\n setDefaultProfilePicture = async () => {\n try {\n await this.props.actions.setDefaultProfileImage(this.props.user.id);\n this.updateSection('');\n this.submitActive = false;\n } catch (err) {\n let serverError;\n if (err.message) {\n serverError = err.message;\n } else {\n serverError = err;\n }\n this.setState({serverError, emailError: '', clientError: '', sectionIsSaving: false});\n }\n }\n\n submitPicture = () => {\n if (!this.state.pictureFile) {\n return;\n }\n\n if (!this.submitActive) {\n return;\n }\n\n trackEvent('settings', 'user_settings_update', {field: 'picture'});\n\n const {formatMessage} = this.props.intl;\n const file = this.state.pictureFile;\n\n if (!AcceptedProfileImageTypes.includes(file.type)) {\n this.setState({clientError: formatMessage(holders.validImage), serverError: ''});\n return;\n } else if (file.size > this.props.maxFileSize) {\n this.setState({clientError: formatMessage(holders.imageTooLarge), serverError: ''});\n return;\n }\n\n this.setState({loadingPicture: true});\n\n this.props.actions.uploadProfileImage(this.props.user.id, file).\n then(({data, error: err}) => {\n if (data) {\n this.updateSection('');\n this.submitActive = false;\n } else if (err) {\n const state = this.setupInitialState(this.props);\n state.serverError = err.message;\n this.setState(state);\n }\n });\n }\n\n submitPosition = () => {\n const user = Object.assign({}, this.props.user);\n const position = this.state.position.trim();\n\n if (user.position === position) {\n this.updateSection('');\n return;\n }\n\n user.position = position;\n\n trackEvent('settings', 'user_settings_update', {field: 'position'});\n\n this.submitUser(user, false);\n }\n\n updateUsername = (e: React.ChangeEvent<HTMLInputElement>) => {\n this.setState({username: e.target.value});\n }\n\n updateFirstName = (e: React.ChangeEvent<HTMLInputElement>) => {\n this.setState({firstName: e.target.value});\n }\n\n updateLastName = (e: React.ChangeEvent<HTMLInputElement>) => {\n this.setState({lastName: e.target.value});\n }\n\n updateNickname = (e: React.ChangeEvent<HTMLInputElement>) => {\n this.setState({nickname: e.target.value});\n }\n\n updatePosition = (e: React.ChangeEvent<HTMLInputElement>) => {\n this.setState({position: e.target.value});\n }\n\n updateEmail = (e: React.ChangeEvent<HTMLInputElement>) => {\n this.setState({email: e.target.value});\n }\n\n updateConfirmEmail = (e: React.ChangeEvent<HTMLInputElement>) => {\n this.setState({confirmEmail: e.target.value});\n }\n\n updateCurrentPassword = (e: React.ChangeEvent<HTMLInputElement>) => {\n this.setState({currentPassword: e.target.value});\n }\n\n updatePicture = (e: React.ChangeEvent<HTMLInputElement>) => {\n if (e.target.files && e.target.files[0]) {\n this.setState({pictureFile: e.target.files[0]});\n\n this.submitActive = true;\n this.setState({clientError: null});\n } else {\n this.setState({pictureFile: null});\n }\n }\n\n updateSection = (section: string) => {\n this.setState(Object.assign({}, this.setupInitialState(this.props), {clientError: '', serverError: '', emailError: '', sectionIsSaving: false}));\n this.submitActive = false;\n this.props.updateSection(section);\n }\n\n setupInitialState(props: Props) {\n const user = props.user;\n\n return {\n username: user.username,\n firstName: user.first_name,\n lastName: user.last_name,\n nickname: user.nickname,\n position: user.position,\n originalEmail: user.email,\n email: '',\n confirmEmail: '',\n currentPassword: '',\n pictureFile: null,\n loadingPicture: false,\n sectionIsSaving: false,\n showSpinner: false,\n serverError: '',\n };\n }\n\n createEmailSection() {\n const {formatMessage} = this.props.intl;\n\n let emailSection;\n if (this.props.activeSection === 'email') {\n const emailVerificationEnabled = this.props.requireEmailVerification;\n const inputs = [];\n\n let helpText = (\n <FormattedMessage\n id='user.settings.general.emailHelp1'\n defaultMessage='Email is used for sign-in, notifications, and password reset. Email requires verification if changed.'\n />\n );\n\n if (!emailVerificationEnabled) {\n helpText = (\n <FormattedMessage\n id='user.settings.general.emailHelp3'\n defaultMessage='Email is used for sign-in, notifications, and password reset.'\n />\n );\n }\n\n let submit = null;\n\n if (this.props.user.auth_service === '') {\n inputs.push(\n <div key='currentEmailSetting'>\n <div className='form-group'>\n <label className='col-sm-5 control-label'>\n <FormattedMessage\n id='user.settings.general.currentEmail'\n defaultMessage='Current Email'\n />\n </label>\n <div className='col-sm-7'>\n <label className='control-label word-break--all text-left'>{this.state.originalEmail}</label>\n </div>\n </div>\n </div>,\n );\n\n inputs.push(\n <div key='emailSetting'>\n <div className='form-group'>\n <label className='col-sm-5 control-label'>\n <FormattedMessage\n id='user.settings.general.newEmail'\n defaultMessage='New Email'\n />\n </label>\n <div className='col-sm-7'>\n <input\n autoFocus={true}\n id='primaryEmail'\n className='form-control'\n type='email'\n onChange={this.updateEmail}\n maxLength={Constants.MAX_EMAIL_LENGTH}\n value={this.state.email}\n aria-label={formatMessage({id: 'user.settings.general.newEmail', defaultMessage: 'New Email'})}\n />\n </div>\n </div>\n </div>,\n );\n\n inputs.push(\n <div key='confirmEmailSetting'>\n <div className='form-group'>\n <label className='col-sm-5 control-label'>\n <FormattedMessage\n id='user.settings.general.confirmEmail'\n defaultMessage='Confirm Email'\n />\n </label>\n <div className='col-sm-7'>\n <input\n id='confirmEmail'\n className='form-control'\n type='email'\n onChange={this.updateConfirmEmail}\n maxLength={Constants.MAX_EMAIL_LENGTH}\n value={this.state.confirmEmail}\n aria-label={formatMessage({id: 'user.settings.general.confirmEmail', defaultMessage: 'Confirm Email'})}\n />\n </div>\n </div>\n </div>,\n );\n\n inputs.push(\n <div key='currentPassword'>\n <div className='form-group'>\n <label className='col-sm-5 control-label'>\n <FormattedMessage\n id='user.settings.general.currentPassword'\n defaultMessage='Current Password'\n />\n </label>\n <div className='col-sm-7'>\n <input\n id='currentPassword'\n className='form-control'\n type='password'\n onChange={this.updateCurrentPassword}\n value={this.state.currentPassword}\n aria-label={formatMessage({id: 'user.settings.general.currentPassword', defaultMessage: 'Current Password'})}\n />\n </div>\n </div>\n {helpText}\n </div>,\n );\n\n submit = this.submitEmail;\n } else if (this.props.user.auth_service === Constants.GITLAB_SERVICE) {\n inputs.push(\n <div\n key='oauthEmailInfo'\n className='form-group'\n >\n <div className='setting-list__hint pb-3'>\n <FormattedMessage\n id='user.settings.general.emailGitlabCantUpdate'\n defaultMessage='Login occurs through GitLab. Email cannot be updated. Email address used for notifications is {email}.'\n values={{\n email: this.state.originalEmail,\n }}\n />\n </div>\n {helpText}\n </div>,\n );\n } else if (this.props.user.auth_service === Constants.GOOGLE_SERVICE) {\n inputs.push(\n <div\n key='oauthEmailInfo'\n className='form-group'\n >\n <div className='setting-list__hint pb-3'>\n <FormattedMessage\n id='user.settings.general.emailGoogleCantUpdate'\n defaultMessage='Login occurs through Google Apps. Email cannot be updated. Email address used for notifications is {email}.'\n values={{\n email: this.state.originalEmail,\n }}\n />\n </div>\n {helpText}\n </div>,\n );\n } else if (this.props.user.auth_service === Constants.OFFICE365_SERVICE) {\n inputs.push(\n <div\n key='oauthEmailInfo'\n className='form-group'\n >\n <div className='setting-list__hint pb-3'>\n <FormattedMessage\n id='user.settings.general.emailOffice365CantUpdate'\n defaultMessage='Login occurs through Office 365. Email cannot be updated. Email address used for notifications is {email}.'\n values={{\n email: this.state.originalEmail,\n }}\n />\n </div>\n {helpText}\n </div>,\n );\n } else if (this.props.user.auth_service === Constants.OPENID_SERVICE) {\n inputs.push(\n <div\n key='oauthEmailInfo'\n className='form-group'\n >\n <div className='setting-list__hint pb-3'>\n <FormattedMessage\n id='user.settings.general.emailOpenIdCantUpdate'\n defaultMessage='Login occurs through OpenID Connect. Email cannot be updated. Email address used for notifications is {email}.'\n values={{\n email: this.state.originalEmail,\n }}\n />\n </div>\n {helpText}\n </div>,\n );\n } else if (this.props.user.auth_service === Constants.LDAP_SERVICE) {\n inputs.push(\n <div\n key='oauthEmailInfo'\n className='pb-2'\n >\n <div className='setting-list__hint pb-3'>\n <FormattedMessage\n id='user.settings.general.emailLdapCantUpdate'\n defaultMessage='Login occurs through AD/LDAP. Email cannot be updated. Email address used for notifications is {email}.'\n values={{\n email: this.state.originalEmail,\n }}\n />\n </div>\n </div>,\n );\n } else if (this.props.user.auth_service === Constants.SAML_SERVICE) {\n inputs.push(\n <div\n key='oauthEmailInfo'\n className='pb-2'\n >\n <div className='setting-list__hint pb-3'>\n <FormattedMessage\n id='user.settings.general.emailSamlCantUpdate'\n defaultMessage='Login occurs through SAML. Email cannot be updated. Email address used for notifications is {email}.'\n values={{\n email: this.state.originalEmail,\n }}\n />\n </div>\n {helpText}\n </div>,\n );\n }\n\n emailSection = (\n <SettingItemMax\n title={\n <FormattedMessage\n id='user.settings.general.email'\n defaultMessage='Email'\n />\n }\n inputs={inputs}\n submit={submit}\n saving={this.state.sectionIsSaving}\n serverError={this.state.serverError}\n clientError={this.state.emailError}\n updateSection={this.updateSection}\n />\n );\n } else {\n let describe: JSX.Element|string = '';\n if (this.props.user.auth_service === '') {\n describe = this.props.user.email;\n } else if (this.props.user.auth_service === Constants.GITLAB_SERVICE) {\n describe = (\n <FormattedMessage\n id='user.settings.general.loginGitlab'\n defaultMessage='Login done through GitLab ({email})'\n values={{\n email: this.state.originalEmail,\n }}\n />\n );\n } else if (this.props.user.auth_service === Constants.GOOGLE_SERVICE) {\n describe = (\n <FormattedMessage\n id='user.settings.general.loginGoogle'\n defaultMessage='Login done through Google Apps ({email})'\n values={{\n email: this.state.originalEmail,\n }}\n />\n );\n } else if (this.props.user.auth_service === Constants.OFFICE365_SERVICE) {\n describe = (\n <FormattedMessage\n id='user.settings.general.loginOffice365'\n defaultMessage='Login done through Office 365 ({email})'\n values={{\n email: this.state.originalEmail,\n }}\n />\n );\n } else if (this.props.user.auth_service === Constants.LDAP_SERVICE) {\n describe = (\n <FormattedMessage\n id='user.settings.general.loginLdap'\n defaultMessage='Login done through AD/LDAP ({email})'\n values={{\n email: this.state.originalEmail,\n }}\n />\n );\n } else if (this.props.user.auth_service === Constants.SAML_SERVICE) {\n describe = (\n <FormattedMessage\n id='user.settings.general.loginSaml'\n defaultMessage='Login done through SAML ({email})'\n values={{\n email: this.state.originalEmail,\n }}\n />\n );\n }\n\n emailSection = (\n <SettingItemMin\n title={\n <FormattedMessage\n id='user.settings.general.email'\n defaultMessage='Email'\n />\n }\n describe={describe}\n section={'email'}\n updateSection={this.updateSection}\n />\n );\n }\n\n return emailSection;\n }\n\n render() {\n const user = this.props.user;\n const {formatMessage} = this.props.intl;\n\n let clientError = null;\n if (this.state.clientError) {\n clientError = this.state.clientError;\n }\n let serverError = null;\n if (this.state.serverError) {\n serverError = this.state.serverError;\n }\n\n let nameSection;\n const inputs = [];\n\n if (this.props.activeSection === 'name') {\n let extraInfo;\n let submit = null;\n if (\n (this.props.user.auth_service === Constants.LDAP_SERVICE &&\n (this.props.ldapFirstNameAttributeSet || this.props.ldapLastNameAttributeSet)) ||\n (this.props.user.auth_service === Constants.SAML_SERVICE &&\n (this.props.samlFirstNameAttributeSet || this.props.samlLastNameAttributeSet)) ||\n (Constants.OAUTH_SERVICES.includes(this.props.user.auth_service))\n ) {\n extraInfo = (\n <span>\n <FormattedMessage\n id='user.settings.general.field_handled_externally'\n defaultMessage='This field is handled through your login provider. If you want to change it, you need to do so through your login provider.'\n />\n </span>\n );\n } else {\n inputs.push(\n <div\n key='firstNameSetting'\n className='form-group'\n >\n <label className='col-sm-5 control-label'>\n <FormattedMessage\n id='user.settings.general.firstName'\n defaultMessage='First Name'\n />\n </label>\n <div className='col-sm-7'>\n <input\n id='firstName'\n autoFocus={true}\n className='form-control'\n type='text'\n onChange={this.updateFirstName}\n maxLength={Constants.MAX_FIRSTNAME_LENGTH}\n value={this.state.firstName}\n onFocus={Utils.moveCursorToEnd}\n aria-label={formatMessage({id: 'user.settings.general.firstName', defaultMessage: 'First Name'})}\n />\n </div>\n </div>,\n );\n\n inputs.push(\n <div\n key='lastNameSetting'\n className='form-group'\n >\n <label className='col-sm-5 control-label'>\n <FormattedMessage\n id='user.settings.general.lastName'\n defaultMessage='Last Name'\n />\n </label>\n <div className='col-sm-7'>\n <input\n id='lastName'\n className='form-control'\n type='text'\n onChange={this.updateLastName}\n maxLength={Constants.MAX_LASTNAME_LENGTH}\n value={this.state.lastName}\n aria-label={formatMessage({id: 'user.settings.general.lastName', defaultMessage: 'Last Name'})}\n />\n </div>\n </div>,\n );\n\n const notifClick = (e: React.MouseEvent<HTMLAnchorElement>) => {\n e.preventDefault();\n this.updateSection('');\n this.props.updateTab('notifications');\n };\n\n const notifLink = (\n <a\n href='#'\n onClick={notifClick.bind(this)}\n >\n <FormattedMessage\n id='user.settings.general.notificationsLink'\n defaultMessage='Notifications'\n />\n </a>\n );\n\n extraInfo = (\n <span>\n <FormattedMessage\n id='user.settings.general.notificationsExtra'\n defaultMessage='By default, you will receive mention notifications when someone types your first name. Go to {notify} settings to change this default.'\n values={{\n notify: (notifLink),\n }}\n />\n </span>\n );\n\n submit = this.submitName;\n }\n\n nameSection = (\n <SettingItemMax\n title={formatMessage(holders.fullName)}\n inputs={inputs}\n submit={submit}\n saving={this.state.sectionIsSaving}\n serverError={serverError}\n clientError={clientError}\n updateSection={this.updateSection}\n extraInfo={extraInfo}\n />\n );\n } else {\n let describe: JSX.Element|string = '';\n\n if (user.first_name && user.last_name) {\n describe = user.first_name + ' ' + user.last_name;\n } else if (user.first_name) {\n describe = user.first_name;\n } else if (user.last_name) {\n describe = user.last_name;\n } else {\n describe = (\n <FormattedMessage\n id='user.settings.general.emptyName'\n defaultMessage=\"Click 'Edit' to add your full name\"\n />\n );\n if (Utils.isMobile()) {\n describe = (\n <FormattedMessage\n id='user.settings.general.mobile.emptyName'\n defaultMessage='Click to add your full name'\n />\n );\n }\n }\n\n nameSection = (\n <SettingItemMin\n title={formatMessage(holders.fullName)}\n describe={describe}\n section={'name'}\n updateSection={this.updateSection}\n />\n );\n }\n\n let nicknameSection;\n if (this.props.activeSection === 'nickname') {\n let extraInfo;\n let submit = null;\n if ((this.props.user.auth_service === 'ldap' && this.props.ldapNicknameAttributeSet) || (this.props.user.auth_service === Constants.SAML_SERVICE && this.props.samlNicknameAttributeSet)) {\n extraInfo = (\n <span>\n <FormattedMessage\n id='user.settings.general.field_handled_externally'\n defaultMessage='This field is handled through your login provider. If you want to change it, you need to do so through your login provider.'\n />\n </span>\n );\n } else {\n let nicknameLabel: JSX.Element|string = (\n <FormattedMessage\n id='user.settings.general.nickname'\n defaultMessage='Nickname'\n />\n );\n if (Utils.isMobile()) {\n nicknameLabel = '';\n }\n\n inputs.push(\n <div\n key='nicknameSetting'\n className='form-group'\n >\n <label className='col-sm-5 control-label'>{nicknameLabel}</label>\n <div className='col-sm-7'>\n <input\n id='nickname'\n autoFocus={true}\n className='form-control'\n type='text'\n onChange={this.updateNickname}\n value={this.state.nickname}\n maxLength={Constants.MAX_NICKNAME_LENGTH}\n autoCapitalize='off'\n aria-label={formatMessage({id: 'user.settings.general.nickname', defaultMessage: 'Nickname'})}\n />\n </div>\n </div>,\n );\n\n extraInfo = (\n <span>\n <FormattedMessage\n id='user.settings.general.nicknameExtra'\n defaultMessage='Use Nickname for a name you might be called that is different from your first name and username. This is most often used when two or more people have similar sounding names and usernames.'\n />\n </span>\n );\n\n submit = this.submitNickname;\n }\n\n nicknameSection = (\n <SettingItemMax\n title={formatMessage(holders.nickname)}\n inputs={inputs}\n submit={submit}\n saving={this.state.sectionIsSaving}\n serverError={serverError}\n clientError={clientError}\n updateSection={this.updateSection}\n extraInfo={extraInfo}\n />\n );\n } else {\n let describe: JSX.Element|string = '';\n if (user.nickname) {\n describe = user.nickname;\n } else {\n describe = (\n <FormattedMessage\n id='user.settings.general.emptyNickname'\n defaultMessage=\"Click 'Edit' to add a nickname\"\n />\n );\n if (Utils.isMobile()) {\n describe = (\n <FormattedMessage\n id='user.settings.general.mobile.emptyNickname'\n defaultMessage='Click to add a nickname'\n />\n );\n }\n }\n\n nicknameSection = (\n <SettingItemMin\n title={formatMessage(holders.nickname)}\n describe={describe}\n section={'nickname'}\n updateSection={this.updateSection}\n />\n );\n }\n\n let usernameSection;\n if (this.props.activeSection === 'username') {\n let extraInfo;\n let submit = null;\n if (this.props.user.auth_service === '') {\n let usernameLabel: JSX.Element | string = (\n <FormattedMessage\n id='user.settings.general.username'\n defaultMessage='Username'\n />\n );\n if (Utils.isMobile()) {\n usernameLabel = '';\n }\n\n inputs.push(\n <div\n key='usernameSetting'\n className='form-group'\n >\n <label className='col-sm-5 control-label'>{usernameLabel}</label>\n <div className='col-sm-7'>\n <input\n id='username'\n autoFocus={true}\n maxLength={Constants.MAX_USERNAME_LENGTH}\n className='form-control'\n type='text'\n onChange={this.updateUsername}\n value={this.state.username}\n autoCapitalize='off'\n onFocus={Utils.moveCursorToEnd}\n aria-label={formatMessage({id: 'user.settings.general.username', defaultMessage: 'Username'})}\n />\n </div>\n </div>,\n );\n\n extraInfo = (\n <span>\n <FormattedMessage\n id='user.settings.general.usernameInfo'\n defaultMessage='Pick something easy for teammates to recognize and recall.'\n />\n </span>\n );\n\n submit = this.submitUsername;\n } else {\n extraInfo = (\n <span>\n <FormattedMessage\n id='user.settings.general.field_handled_externally'\n defaultMessage='This field is handled through your login provider. If you want to change it, you need to do so through your login provider.'\n />\n </span>\n );\n }\n\n usernameSection = (\n <SettingItemMax\n title={formatMessage(holders.username)}\n inputs={inputs}\n submit={submit}\n saving={this.state.sectionIsSaving}\n serverError={serverError}\n clientError={clientError}\n updateSection={this.updateSection}\n extraInfo={extraInfo}\n />\n );\n } else {\n usernameSection = (\n <SettingItemMin\n title={formatMessage(holders.username)}\n describe={this.props.user.username}\n section={'username'}\n updateSection={this.updateSection}\n />\n );\n }\n\n let positionSection;\n if (this.props.activeSection === 'position') {\n let extraInfo: JSX.Element|string;\n let submit = null;\n if ((this.props.user.auth_service === Constants.LDAP_SERVICE && this.props.ldapPositionAttributeSet) || (this.props.user.auth_service === Constants.SAML_SERVICE && this.props.samlPositionAttributeSet)) {\n extraInfo = (\n <span>\n <FormattedMessage\n id='user.settings.general.field_handled_externally'\n defaultMessage='This field is handled through your login provider. If you want to change it, you need to do so through your login provider.'\n />\n </span>\n );\n } else {\n let positionLabel: JSX.Element | string = (\n <FormattedMessage\n id='user.settings.general.position'\n defaultMessage='Position'\n />\n );\n if (Utils.isMobile()) {\n positionLabel = '';\n }\n\n inputs.push(\n <div\n key='positionSetting'\n className='form-group'\n >\n <label className='col-sm-5 control-label'>{positionLabel}</label>\n <div className='col-sm-7'>\n <input\n id='position'\n autoFocus={true}\n className='form-control'\n type='text'\n onChange={this.updatePosition}\n value={this.state.position}\n maxLength={Constants.MAX_POSITION_LENGTH}\n autoCapitalize='off'\n onFocus={Utils.moveCursorToEnd}\n aria-label={formatMessage({id: 'user.settings.general.position', defaultMessage: 'Position'})}\n />\n </div>\n </div>,\n );\n\n extraInfo = (\n <span>\n <FormattedMessage\n id='user.settings.general.positionExtra'\n defaultMessage='Use Position for your role or job title. This will be shown in your profile popover.'\n />\n </span>\n );\n\n submit = this.submitPosition;\n }\n\n positionSection = (\n <SettingItemMax\n title={formatMessage(holders.position)}\n inputs={inputs}\n submit={submit}\n saving={this.state.sectionIsSaving}\n serverError={serverError}\n clientError={clientError}\n updateSection={this.updateSection}\n extraInfo={extraInfo}\n />\n );\n } else {\n let describe: JSX.Element|string = '';\n if (user.position) {\n describe = user.position;\n } else {\n describe = (\n <FormattedMessage\n id='user.settings.general.emptyPosition'\n defaultMessage=\"Click 'Edit' to add your job title / position\"\n />\n );\n if (Utils.isMobile()) {\n describe = (\n <FormattedMessage\n id='user.settings.general.mobile.emptyPosition'\n defaultMessage='Click to add your job title / position'\n />\n );\n }\n }\n\n positionSection = (\n <SettingItemMin\n title={formatMessage(holders.position)}\n describe={describe}\n section={'position'}\n updateSection={this.updateSection}\n />\n );\n }\n\n const emailSection = this.createEmailSection();\n\n let pictureSection;\n if (this.props.activeSection === 'picture') {\n let submit = null;\n let setDefault = null;\n let helpText = null;\n let imgSrc = null;\n\n if ((this.props.user.auth_service === Constants.LDAP_SERVICE || this.props.user.auth_service === Constants.SAML_SERVICE) && this.props.ldapPictureAttributeSet) {\n helpText = (\n <span>\n <FormattedMessage\n id='user.settings.general.field_handled_externally'\n defaultMessage='This field is handled through your login provider. If you want to change it, you need to do so through your login provider.'\n />\n </span>\n );\n } else {\n submit = this.submitPicture;\n setDefault = user.last_picture_update > 0 ? this.setDefaultProfilePicture : null;\n imgSrc = Utils.imageURLForUser(user.id, user.last_picture_update);\n helpText = (\n <FormattedMessage\n id={'setting_picture.help.profile'}\n defaultMessage='Upload a picture in BMP, JPG, JPEG, or PNG format. Maximum file size: {max}'\n values={{max: Utils.fileSizeToString(this.props.maxFileSize)}}\n />\n );\n }\n\n pictureSection = (\n <SettingPicture\n title={formatMessage(holders.profilePicture)}\n onSubmit={submit}\n onSetDefault={setDefault}\n src={imgSrc}\n defaultImageSrc={Utils.defaultImageURLForUser(user.id)}\n serverError={serverError}\n clientError={clientError}\n updateSection={(e: MouseEvent) => {\n this.updateSection('');\n e.preventDefault();\n }}\n file={this.state.pictureFile}\n onFileChange={this.updatePicture}\n submitActive={this.submitActive}\n loadingPicture={this.state.loadingPicture}\n maxFileSize={this.props.maxFileSize}\n helpText={helpText}\n />\n );\n } else {\n let minMessage: JSX.Element|string = formatMessage(holders.uploadImage);\n if (Utils.isMobile()) {\n minMessage = formatMessage(holders.uploadImageMobile);\n }\n if (user.last_picture_update) {\n minMessage = (\n <FormattedMessage\n id='user.settings.general.imageUpdated'\n defaultMessage='Image last updated {date}'\n values={{\n date: (\n <FormattedDate\n value={new Date(user.last_picture_update)}\n day='2-digit'\n month='short'\n year='numeric'\n />\n ),\n }}\n />\n );\n }\n pictureSection = (\n <SettingItemMin\n title={formatMessage(holders.profilePicture)}\n describe={minMessage}\n section={'picture'}\n updateSection={this.updateSection}\n />\n );\n }\n\n return (\n <div id='generalSettings'>\n <div className='modal-header'>\n <button\n id='closeUserSettings'\n type='button'\n className='close'\n data-dismiss='modal'\n aria-label={formatMessage(holders.close)}\n onClick={this.props.closeModal}\n >\n <span aria-hidden='true'>{'×'}</span>\n </button>\n <h4\n className='modal-title'\n ref='title'\n >\n <div className='modal-back'>\n <FormattedMessage\n id='generic_icons.collapse'\n defaultMessage='Collapse Icon'\n >\n {(title?: string) => (\n <i\n className='fa fa-angle-left'\n title={title}\n onClick={this.props.collapseModal}\n />\n )}\n </FormattedMessage>\n </div>\n <FormattedMessage\n id='user.settings.modal.profile'\n defaultMessage='Profile'\n />\n </h4>\n </div>\n <div className='user-settings'>\n <h3\n id='generalSettingsTitle'\n className='tab-header'\n >\n <FormattedMessage\n id='user.settings.modal.profile'\n defaultMessage='Profile'\n />\n </h3>\n <div className='divider-dark first'/>\n {nameSection}\n <div className='divider-light'/>\n {usernameSection}\n <div className='divider-light'/>\n {nicknameSection}\n <div className='divider-light'/>\n {positionSection}\n <div className='divider-light'/>\n {emailSection}\n <div className='divider-light'/>\n {pictureSection}\n <div className='divider-dark'/>\n </div>\n </div>\n );\n }\n}\n\nexport default injectIntl(UserSettingsGeneralTab);\n/* eslint-enable react/no-string-refs */\n","// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.\n// See LICENSE.txt for license information.\n\nimport {connect} from 'react-redux';\nimport {bindActionCreators, Dispatch, ActionCreatorsMapObject} from 'redux';\n\nimport {\n getMe,\n updateMe,\n sendVerificationEmail,\n setDefaultProfileImage,\n uploadProfileImage,\n} from 'mattermost-redux/actions/users';\nimport {clearErrors, logError} from 'mattermost-redux/actions/errors';\nimport {getConfig} from 'mattermost-redux/selectors/entities/general';\n\nimport {GlobalState} from 'mattermost-redux/types/store';\nimport {ActionFunc} from 'mattermost-redux/types/actions';\n\nimport UserSettingsGeneralTab, {Props} from './user_settings_general';\n\nfunction mapStateToProps(state: GlobalState) {\n const config = getConfig(state);\n\n const requireEmailVerification = config.RequireEmailVerification === 'true';\n const maxFileSize = parseInt(config.MaxFileSize!, 10);\n const ldapFirstNameAttributeSet = config.LdapFirstNameAttributeSet === 'true';\n const ldapLastNameAttributeSet = config.LdapLastNameAttributeSet === 'true';\n const samlFirstNameAttributeSet = config.SamlFirstNameAttributeSet === 'true';\n const samlLastNameAttributeSet = config.SamlLastNameAttributeSet === 'true';\n const ldapNicknameAttributeSet = config.LdapNicknameAttributeSet === 'true';\n const samlNicknameAttributeSet = config.SamlNicknameAttributeSet === 'true';\n const samlPositionAttributeSet = config.SamlPositionAttributeSet === 'true';\n const ldapPositionAttributeSet = config.LdapPositionAttributeSet === 'true';\n const ldapPictureAttributeSet = config.LdapPictureAttributeSet === 'true';\n\n return {\n requireEmailVerification,\n maxFileSize,\n ldapFirstNameAttributeSet,\n ldapLastNameAttributeSet,\n samlFirstNameAttributeSet,\n samlLastNameAttributeSet,\n ldapNicknameAttributeSet,\n samlNicknameAttributeSet,\n samlPositionAttributeSet,\n ldapPositionAttributeSet,\n ldapPictureAttributeSet,\n };\n}\n\nfunction mapDispatchToProps(dispatch: Dispatch) {\n return {\n actions: bindActionCreators<ActionCreatorsMapObject<ActionFunc>, Props['actions']>({\n logError,\n clearErrors,\n getMe,\n updateMe,\n sendVerificationEmail,\n setDefaultProfileImage,\n uploadProfileImage,\n }, dispatch),\n };\n}\n\nexport default connect(mapStateToProps, mapDispatchToProps)(UserSettingsGeneralTab);\n","// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.\n// See LICENSE.txt for license information.\n\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport ReactSelect from 'react-select';\nimport {FormattedMessage} from 'react-intl';\n\nimport semver from 'semver';\n\nimport {NotificationLevels} from 'utils/constants';\nimport * as Utils from 'utils/utils.jsx';\nimport {t} from 'utils/i18n.jsx';\nimport SettingItemMax from 'components/setting_item_max.jsx';\nimport SettingItemMin from 'components/setting_item_min';\nimport {isDesktopApp} from 'utils/user_agent';\n\nexport default class DesktopNotificationSettings extends React.PureComponent {\n constructor(props) {\n super(props);\n const selectedOption = {value: props.selectedSound, label: props.selectedSound};\n this.state = {\n selectedOption,\n blurDropdown: false,\n };\n this.dropdownSoundRef = React.createRef();\n }\n\n handleMinUpdateSection = (section) => {\n this.props.updateSection(section);\n\n this.props.cancel();\n }\n\n handleMaxUpdateSection = (section) => {\n this.props.updateSection(section);\n }\n\n handleOnChange = (e) => {\n const key = e.currentTarget.getAttribute('data-key');\n const value = e.currentTarget.getAttribute('data-value');\n this.props.setParentState(key, value);\n }\n\n handleThreadsOnChange = (e) => {\n const value = e.target.checked ? NotificationLevels.ALL : NotificationLevels.MENTION;\n this.props.setParentState('desktopThreads', value);\n }\n\n setDesktopNotificationSound = (selectedOption) => {\n this.props.setParentState('desktopNotificationSound', selectedOption.value);\n this.setState({selectedOption});\n Utils.tryNotificationSound(selectedOption.value);\n }\n\n blurDropdown() {\n if (!this.state.blurDropdown) {\n this.setState({blurDropdown: true});\n if (this.dropdownSoundRef.current) {\n this.dropdownSoundRef.current.blur();\n }\n }\n }\n\n buildMaximizedSetting = () => {\n const inputs = [];\n\n const activityRadio = [false, false, false];\n if (this.props.activity === NotificationLevels.MENTION) {\n activityRadio[1] = true;\n } else if (this.props.activity === NotificationLevels.NONE) {\n activityRadio[2] = true;\n } else {\n activityRadio[0] = true;\n }\n\n let soundSection;\n let notificationSelection;\n let threadsNotificationSelection;\n if (this.props.activity !== NotificationLevels.NONE) {\n const soundRadio = [false, false];\n if (this.props.sound === 'false') {\n soundRadio[1] = true;\n } else {\n soundRadio[0] = true;\n }\n\n if (this.props.sound === 'true') {\n const sounds = Array.from(Utils.notificationSounds.keys());\n const options = sounds.map((sound) => {\n return {value: sound, label: sound};\n });\n\n if (!isDesktopApp() || (window.desktop && semver.gte(window.desktop.version, '4.6.0'))) {\n notificationSelection = (<div className='pt-2'>\n <ReactSelect\n className='react-select notification-sound-dropdown'\n classNamePrefix='react-select'\n id='displaySoundNotification'\n options={options}\n clearable={false}\n onChange={this.setDesktopNotificationSound}\n value={this.state.selectedOption}\n isSearchable={false}\n ref={this.dropdownSoundRef}\n /></div>);\n }\n }\n\n if (Utils.hasSoundOptions()) {\n soundSection = (\n <fieldset>\n <legend className='form-legend'>\n <FormattedMessage\n id='user.settings.notifications.desktop.sound'\n defaultMessage='Notification sound'\n />\n </legend>\n <div className='radio'>\n <label>\n <input\n id='soundOn'\n type='radio'\n name='notificationSounds'\n checked={soundRadio[0]}\n data-key={'desktopSound'}\n data-value={'true'}\n onChange={this.handleOnChange}\n />\n <FormattedMessage\n id='user.settings.notifications.on'\n defaultMessage='On'\n />\n </label>\n <br/>\n </div>\n <div className='radio'>\n <label>\n <input\n id='soundOff'\n type='radio'\n name='notificationSounds'\n checked={soundRadio[1]}\n data-key={'desktopSound'}\n data-value={'false'}\n onChange={this.handleOnChange}\n />\n <FormattedMessage\n id='user.settings.notifications.off'\n defaultMessage='Off'\n />\n </label>\n <br/>\n </div>\n {notificationSelection}\n <div className='mt-5'>\n <FormattedMessage\n id='user.settings.notifications.sounds_info'\n defaultMessage='Notification sounds are available on Firefox, Edge, Safari, Chrome and Mattermost Desktop Apps.'\n />\n </div>\n </fieldset>\n );\n } else {\n soundSection = (\n <fieldset>\n <legend className='form-legend'>\n <FormattedMessage\n id='user.settings.notifications.desktop.sound'\n defaultMessage='Notification sound'\n />\n </legend>\n <br/>\n <FormattedMessage\n id='user.settings.notifications.soundConfig'\n defaultMessage='Please configure notification sounds in your browser settings'\n />\n </fieldset>\n );\n }\n }\n\n if (this.props.isCollapsedThreadsEnabled && NotificationLevels.MENTION === this.props.activity) {\n threadsNotificationSelection = (\n <>\n <fieldset>\n <legend className='form-legend'>\n <FormattedMessage\n id='user.settings.notifications.threads.desktop'\n defaultMessage='Thread reply notifications'\n />\n </legend>\n <div className='checkbox'>\n <label>\n <input\n id='desktopThreadsNotificationAllActivity'\n type='checkbox'\n name='desktopThreadsNotificationLevel'\n checked={this.props.threads === NotificationLevels.ALL}\n onChange={this.handleThreadsOnChange}\n />\n <FormattedMessage\n id='user.settings.notifications.threads.allActivity'\n defaultMessage={'Notify me about threads I\\'m following'}\n />\n </label>\n <br/>\n </div>\n <div className='mt-5'>\n <FormattedMessage\n id='user.settings.notifications.threads'\n defaultMessage={'When enabled, any replies to a thread you\\'re following will send a desktop notification.'}\n />\n </div>\n </fieldset>\n <hr/>\n </>\n );\n }\n\n inputs.push(\n <div key='userNotificationLevelOption'>\n <fieldset>\n <legend className='form-legend'>\n <FormattedMessage\n id='user.settings.notifications.desktop'\n defaultMessage='Send desktop notifications'\n />\n </legend>\n <div className='radio'>\n <label>\n <input\n id='desktopNotificationAllActivity'\n type='radio'\n name='desktopNotificationLevel'\n checked={activityRadio[0]}\n data-key={'desktopActivity'}\n data-value={NotificationLevels.ALL}\n onChange={this.handleOnChange}\n />\n <FormattedMessage\n id='user.settings.notifications.allActivity'\n defaultMessage='For all activity'\n />\n </label>\n <br/>\n </div>\n <div className='radio'>\n <label>\n <input\n id='desktopNotificationMentions'\n type='radio'\n name='desktopNotificationLevel'\n checked={activityRadio[1]}\n data-key={'desktopActivity'}\n data-value={NotificationLevels.MENTION}\n onChange={this.handleOnChange}\n />\n <FormattedMessage\n id='user.settings.notifications.onlyMentions'\n defaultMessage='Only for mentions and direct messages'\n />\n </label>\n <br/>\n </div>\n <div className='radio'>\n <label>\n <input\n id='desktopNotificationNever'\n type='radio'\n name='desktopNotificationLevel'\n checked={activityRadio[2]}\n data-key={'desktopActivity'}\n data-value={NotificationLevels.NONE}\n onChange={this.handleOnChange}\n />\n <FormattedMessage\n id='user.settings.notifications.never'\n defaultMessage='Never'\n />\n </label>\n </div>\n <div className='mt-5'>\n <FormattedMessage\n id='user.settings.notifications.info'\n defaultMessage='Desktop notifications are available on Edge, Firefox, Safari, Chrome and Mattermost Desktop Apps.'\n />\n </div>\n </fieldset>\n <hr/>\n {threadsNotificationSelection}\n {soundSection}\n </div>,\n );\n\n return (\n <SettingItemMax\n title={Utils.localizeMessage('user.settings.notifications.desktop.title', 'Desktop Notifications')}\n inputs={inputs}\n submit={this.props.submit}\n saving={this.props.saving}\n server_error={this.props.error}\n updateSection={this.handleMaxUpdateSection}\n />\n );\n }\n\n buildMinimizedSetting = () => {\n let formattedMessageProps;\n const hasSoundOption = Utils.hasSoundOptions();\n if (this.props.activity === NotificationLevels.MENTION) {\n if (hasSoundOption && this.props.sound !== 'false') {\n formattedMessageProps = {\n id: t('user.settings.notifications.desktop.mentionsSound'),\n defaultMessage: 'For mentions and direct messages, with sound',\n };\n } else if (hasSoundOption && this.props.sound === 'false') {\n formattedMessageProps = {\n id: t('user.settings.notifications.desktop.mentionsNoSound'),\n defaultMessage: 'For mentions and direct messages, without sound',\n };\n } else {\n formattedMessageProps = {\n id: t('user.settings.notifications.desktop.mentionsSoundHidden'),\n defaultMessage: 'For mentions and direct messages',\n };\n }\n } else if (this.props.activity === NotificationLevels.NONE) {\n formattedMessageProps = {\n id: t('user.settings.notifications.off'),\n defaultMessage: 'Off',\n };\n } else {\n if (hasSoundOption && this.props.sound !== 'false') { //eslint-disable-line no-lonely-if\n formattedMessageProps = {\n id: t('user.settings.notifications.desktop.allSound'),\n defaultMessage: 'For all activity, with sound',\n };\n } else if (hasSoundOption && this.props.sound === 'false') {\n formattedMessageProps = {\n id: t('user.settings.notifications.desktop.allNoSound'),\n defaultMessage: 'For all activity, without sound',\n };\n } else {\n formattedMessageProps = {\n id: t('user.settings.notifications.desktop.allSoundHidden'),\n defaultMessage: 'For all activity',\n };\n }\n }\n\n return (\n <SettingItemMin\n title={Utils.localizeMessage('user.settings.notifications.desktop.title', 'Desktop Notifications')}\n describe={<FormattedMessage {...formattedMessageProps}/>}\n focused={this.props.focused}\n section={'desktop'}\n updateSection={this.handleMinUpdateSection}\n />\n );\n }\n\n componentDidUpdate() {\n this.blurDropdown();\n }\n\n render() {\n if (this.props.active) {\n return this.buildMaximizedSetting();\n }\n\n return this.buildMinimizedSetting();\n }\n}\n\nDesktopNotificationSettings.propTypes = {\n activity: PropTypes.string.isRequired,\n threads: PropTypes.string.isRequired,\n sound: PropTypes.string.isRequired,\n updateSection: PropTypes.func,\n setParentState: PropTypes.func,\n submit: PropTypes.func,\n cancel: PropTypes.func,\n error: PropTypes.string,\n active: PropTypes.bool,\n saving: PropTypes.bool,\n focused: PropTypes.bool,\n selectedSound: PropTypes.string,\n isCollapsedThreadsEnabled: PropTypes.bool.isRequired,\n};\n","// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.\n// See LICENSE.txt for license information.\nimport {Preferences} from '../constants';\nexport function getEmailInterval(enableEmailNotification: boolean, enableEmailBatching: boolean, emailIntervalPreference: number): number {\n const {\n INTERVAL_NEVER,\n INTERVAL_IMMEDIATE,\n INTERVAL_FIFTEEN_MINUTES,\n INTERVAL_HOUR,\n } = Preferences;\n\n const validValuesWithEmailBatching = [INTERVAL_IMMEDIATE, INTERVAL_NEVER, INTERVAL_FIFTEEN_MINUTES, INTERVAL_HOUR];\n const validValuesWithoutEmailBatching = [INTERVAL_IMMEDIATE, INTERVAL_NEVER];\n\n if (!enableEmailNotification) {\n return INTERVAL_NEVER;\n } else if (enableEmailBatching && validValuesWithEmailBatching.indexOf(emailIntervalPreference) === -1) {\n // When email batching is enabled, the default interval is 15 minutes\n return INTERVAL_FIFTEEN_MINUTES;\n } else if (!enableEmailBatching && validValuesWithoutEmailBatching.indexOf(emailIntervalPreference) === -1) {\n // When email batching is not enabled, the default interval is immediately\n return INTERVAL_IMMEDIATE;\n } else if (enableEmailNotification && emailIntervalPreference === INTERVAL_NEVER) {\n // When email notification is enabled, the default interval is immediately\n return INTERVAL_IMMEDIATE;\n }\n\n return emailIntervalPreference;\n}\n","// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.\n// See LICENSE.txt for license information.\n\nimport React from 'react';\nimport {FormattedMessage} from 'react-intl';\n\nimport {getEmailInterval} from 'mattermost-redux/utils/notify_props';\nimport {PreferenceType} from 'mattermost-redux/types/preferences';\n\nimport {Preferences, NotificationLevels} from 'utils/constants';\nimport {localizeMessage} from 'utils/utils.jsx';\nimport SettingItemMax from 'components/setting_item_max.jsx';\nimport SettingItemMin from 'components/setting_item_min';\n\nconst SECONDS_PER_MINUTE = 60;\n\ntype Props = {\n currentUserId: string;\n activeSection: string;\n updateSection: (section: string) => void;\n enableEmail: boolean;\n emailInterval: number;\n onSubmit: () => void;\n onCancel: () => void;\n onChange: (enableEmail: string) => void;\n serverError?: string;\n saving?: boolean;\n sendEmailNotifications: boolean;\n enableEmailBatching: boolean;\n actions: {\n savePreferences: (currentUserId: string, emailIntervalPreference: PreferenceType[]) =>\n Promise<{data: boolean}>;\n };\n isCollapsedThreadsEnabled: boolean;\n threads: string;\n setParentState: (key: string, value: any) => void;\n};\n\ntype State = {\n activeSection: string;\n emailInterval: number;\n enableEmail: boolean;\n enableEmailBatching: boolean;\n sendEmailNotifications: boolean;\n newInterval: number;\n};\n\nexport default class EmailNotificationSetting extends React.PureComponent<Props, State> {\n constructor(props: Props) {\n super(props);\n\n const {\n emailInterval,\n enableEmail,\n enableEmailBatching,\n sendEmailNotifications,\n activeSection,\n } = props;\n\n this.state = {\n activeSection,\n emailInterval,\n enableEmail,\n enableEmailBatching,\n sendEmailNotifications,\n newInterval: getEmailInterval(enableEmail && sendEmailNotifications, enableEmailBatching, emailInterval),\n };\n }\n\n static getDerivedStateFromProps(nextProps: Props, prevState: State) {\n const {\n emailInterval,\n enableEmail,\n enableEmailBatching,\n sendEmailNotifications,\n activeSection,\n } = nextProps;\n\n // If we're re-opening this section, reset to defaults from props\n if (activeSection === 'email' && prevState.activeSection !== 'email') {\n return {\n activeSection,\n emailInterval,\n enableEmail,\n enableEmailBatching,\n sendEmailNotifications,\n newInterval: getEmailInterval(enableEmail && sendEmailNotifications, enableEmailBatching, emailInterval),\n };\n }\n\n if (sendEmailNotifications !== prevState.sendEmailNotifications ||\n enableEmailBatching !== prevState.enableEmailBatching ||\n emailInterval !== prevState.emailInterval ||\n activeSection !== prevState.activeSection\n ) {\n return {\n activeSection,\n emailInterval,\n enableEmail,\n enableEmailBatching,\n sendEmailNotifications,\n newInterval: getEmailInterval(enableEmail && sendEmailNotifications, enableEmailBatching, emailInterval),\n };\n }\n\n return null;\n }\n\n handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n const enableEmail = e.currentTarget.getAttribute('data-enable-email')!;\n const newInterval = parseInt(e.currentTarget.getAttribute('data-email-interval')!, 10);\n\n this.setState({\n enableEmail: enableEmail === 'true',\n newInterval,\n });\n\n this.props.onChange(enableEmail);\n }\n\n handleThreadsOnChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n const value = e.target.checked ? NotificationLevels.ALL : NotificationLevels.MENTION;\n this.props.setParentState('emailThreads', value);\n }\n\n handleSubmit = async () => {\n const {newInterval} = this.state;\n if (this.props.emailInterval === newInterval && this.props.enableEmail === this.state.enableEmail) {\n this.props.updateSection('');\n } else {\n // until the rest of the notification settings are moved to preferences, we have to do this separately\n const {currentUserId, actions} = this.props;\n const emailIntervalPreference = {\n user_id: currentUserId,\n category: Preferences.CATEGORY_NOTIFICATIONS,\n name: Preferences.EMAIL_INTERVAL,\n value: newInterval.toString(),\n };\n\n await actions.savePreferences(currentUserId, [emailIntervalPreference]);\n }\n\n this.props.onSubmit();\n }\n\n handleUpdateSection = (section?: string) => {\n if (section) {\n this.props.updateSection(section);\n } else {\n this.props.updateSection('');\n\n this.setState({\n enableEmail: this.props.enableEmail,\n newInterval: this.props.emailInterval,\n });\n this.props.onCancel();\n }\n }\n\n renderMinSettingView = () => {\n const {\n enableEmail,\n sendEmailNotifications,\n } = this.props;\n\n const {newInterval} = this.state;\n\n let description;\n if (!sendEmailNotifications) {\n description = (\n <FormattedMessage\n id='user.settings.notifications.email.disabled'\n defaultMessage='Email notifications are not enabled'\n />\n );\n } else if (enableEmail) {\n switch (newInterval) {\n case Preferences.INTERVAL_IMMEDIATE:\n description = (\n <FormattedMessage\n id='user.settings.notifications.email.immediately'\n defaultMessage='Immediately'\n />\n );\n break;\n case Preferences.INTERVAL_HOUR:\n description = (\n <FormattedMessage\n id='user.settings.notifications.email.everyHour'\n defaultMessage='Every hour'\n />\n );\n break;\n case Preferences.INTERVAL_FIFTEEN_MINUTES:\n description = (\n <FormattedMessage\n id='user.settings.notifications.email.everyXMinutes'\n defaultMessage='Every {count, plural, one {minute} other {{count, number} minutes}}'\n values={{count: newInterval / SECONDS_PER_MINUTE}}\n />\n );\n break;\n default:\n description = (\n <FormattedMessage\n id='user.settings.notifications.email.never'\n defaultMessage='Never'\n />\n );\n }\n } else {\n description = (\n <FormattedMessage\n id='user.settings.notifications.email.never'\n defaultMessage='Never'\n />\n );\n }\n\n return (\n <SettingItemMin\n title={localizeMessage('user.settings.notifications.emailNotifications', 'Email Notifications')}\n describe={description}\n section={'email'}\n updateSection={this.handleUpdateSection}\n />\n );\n }\n\n renderMaxSettingView = () => {\n if (!this.props.sendEmailNotifications) {\n return (\n <SettingItemMax\n title={localizeMessage('user.settings.notifications.emailNotifications', 'Email Notifications')}\n inputs={[\n <div\n key='oauthEmailInfo'\n className='pt-2'\n >\n <FormattedMessage\n id='user.settings.notifications.email.disabled_long'\n defaultMessage='Email notifications have not been enabled by your System Administrator.'\n />\n </div>,\n ]}\n server_error={this.props.serverError}\n section={'email'}\n updateSection={this.handleUpdateSection}\n />\n );\n }\n\n const {newInterval} = this.state;\n let batchingOptions = null;\n let batchingInfo = null;\n if (this.props.enableEmailBatching) {\n batchingOptions = (\n <fieldset>\n <div className='radio'>\n <label>\n <input\n id='emailNotificationMinutes'\n type='radio'\n name='emailNotifications'\n checked={newInterval === Preferences.INTERVAL_FIFTEEN_MINUTES}\n data-enable-email={'true'}\n data-email-interval={Preferences.INTERVAL_FIFTEEN_MINUTES}\n onChange={this.handleChange}\n />\n <FormattedMessage\n id='user.settings.notifications.email.everyXMinutes'\n defaultMessage='Every {count} minutes'\n values={{count: Preferences.INTERVAL_FIFTEEN_MINUTES / SECONDS_PER_MINUTE}}\n />\n </label>\n </div>\n <div className='radio'>\n <label>\n <input\n id='emailNotificationHour'\n type='radio'\n name='emailNotifications'\n checked={newInterval === Preferences.INTERVAL_HOUR}\n data-enable-email={'true'}\n data-email-interval={Preferences.INTERVAL_HOUR}\n onChange={this.handleChange}\n />\n <FormattedMessage\n id='user.settings.notifications.email.everyHour'\n defaultMessage='Every hour'\n />\n </label>\n </div>\n </fieldset>\n );\n\n batchingInfo = (\n <FormattedMessage\n id='user.settings.notifications.emailBatchingInfo'\n defaultMessage='Notifications received over the time period selected are combined and sent in a single email.'\n />\n );\n }\n\n let threadsNotificationSelection = null;\n if (this.props.isCollapsedThreadsEnabled && this.props.enableEmail) {\n threadsNotificationSelection = (\n <React.Fragment key='userNotificationEmailThreadsOptions'>\n <hr/>\n <fieldset>\n <legend className='form-legend'>\n <FormattedMessage\n id='user.settings.notifications.threads.desktop'\n defaultMessage='Thread reply notifications'\n />\n </legend>\n <div className='checkbox'>\n <label>\n <input\n id='desktopThreadsNotificationAllActivity'\n type='checkbox'\n name='desktopThreadsNotificationLevel'\n checked={this.props.threads === NotificationLevels.ALL}\n onChange={this.handleThreadsOnChange}\n />\n <FormattedMessage\n id='user.settings.notifications.threads.allActivity'\n defaultMessage={'Notify me about threads I\\'m following'}\n />\n </label>\n <br/>\n </div>\n <div className='mt-5'>\n <FormattedMessage\n id='user.settings.notifications.threads'\n defaultMessage={'When enabled, any replies to a thread you\\'re following will send a desktop notification.'}\n />\n </div>\n </fieldset>\n </React.Fragment>\n );\n }\n\n return (\n <SettingItemMax\n title={localizeMessage('user.settings.notifications.emailNotifications', 'Email Notifications')}\n inputs={[\n <fieldset key='userNotificationEmailOptions'>\n <legend className='form-legend'>\n <FormattedMessage\n id='user.settings.notifications.email.send'\n defaultMessage='Send email notifications'\n />\n </legend>\n <div className='radio'>\n <label>\n <input\n id='emailNotificationImmediately'\n type='radio'\n name='emailNotifications'\n checked={newInterval === Preferences.INTERVAL_IMMEDIATE}\n data-enable-email={'true'}\n data-email-interval={Preferences.INTERVAL_IMMEDIATE}\n onChange={this.handleChange}\n />\n <FormattedMessage\n id='user.settings.notifications.email.immediately'\n defaultMessage='Immediately'\n />\n </label>\n </div>\n {batchingOptions}\n <div className='radio'>\n <label>\n <input\n id='emailNotificationNever'\n type='radio'\n name='emailNotifications'\n checked={newInterval === Preferences.INTERVAL_NEVER}\n data-enable-email={'false'}\n data-email-interval={Preferences.INTERVAL_NEVER}\n onChange={this.handleChange}\n />\n <FormattedMessage\n id='user.settings.notifications.email.never'\n defaultMessage='Never'\n />\n </label>\n </div>\n <div className='mt-3'>\n <FormattedMessage\n id='user.settings.notifications.emailInfo'\n defaultMessage='Email notifications are sent for mentions and direct messages when you are offline or away for more than 5 minutes.'\n />\n {' '}\n {batchingInfo}\n </div>\n </fieldset>,\n threadsNotificationSelection,\n ]}\n submit={this.handleSubmit}\n saving={this.props.saving}\n server_error={this.props.serverError}\n updateSection={this.handleUpdateSection}\n />\n );\n }\n\n render() {\n if (this.props.activeSection !== 'email') {\n return this.renderMinSettingView();\n }\n\n return this.renderMaxSettingView();\n }\n}\n","// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.\n// See LICENSE.txt for license information.\n\nimport {connect} from 'react-redux';\nimport {bindActionCreators, Dispatch, ActionCreatorsMapObject} from 'redux';\n\nimport {Preferences} from 'mattermost-redux/constants';\n\nimport {savePreferences} from 'mattermost-redux/actions/preferences';\nimport {PreferenceType} from 'mattermost-redux/types/preferences';\n\nimport {getCurrentUserId} from 'mattermost-redux/selectors/entities/common';\nimport {getConfig} from 'mattermost-redux/selectors/entities/general';\nimport {get as getPreference} from 'mattermost-redux/selectors/entities/preferences';\nimport {GlobalState} from 'mattermost-redux/types/store';\nimport {ActionFunc} from 'mattermost-redux/types/actions';\n\nimport EmailNotificationSetting from './email_notification_setting';\n\ntype Actions = {\n savePreferences: (currentUserId: string, emailIntervalPreference: PreferenceType[]) =>\n Promise<{data: boolean}>;\n}\n\nfunction mapStateToProps(state: GlobalState) {\n const config = getConfig(state);\n const emailInterval = parseInt(getPreference(\n state,\n Preferences.CATEGORY_NOTIFICATIONS,\n Preferences.EMAIL_INTERVAL,\n Preferences.INTERVAL_NOT_SET.toString(),\n ), 10);\n\n return {\n currentUserId: getCurrentUserId(state),\n emailInterval,\n enableEmailBatching: config.EnableEmailBatching === 'true',\n sendEmailNotifications: config.SendEmailNotifications === 'true',\n };\n}\n\nfunction mapDispatchToProps(dispatch: Dispatch) {\n return {\n actions: bindActionCreators<ActionCreatorsMapObject<ActionFunc>, Actions>({\n savePreferences,\n }, dispatch),\n };\n}\n\nexport default connect(mapStateToProps, mapDispatchToProps)(EmailNotificationSetting);\n","// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.\n// See LICENSE.txt for license information.\n\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport {FormattedMessage} from 'react-intl';\n\nimport AutosizeTextarea from 'components/autosize_textarea';\nimport SettingItemMax from 'components/setting_item_max.jsx';\nimport {localizeMessage} from 'utils/utils.jsx';\n\nconst MESSAGE_MAX_LENGTH = 200;\n\nexport default class ManageAutoResponder extends React.PureComponent {\n static propTypes = {\n autoResponderActive: PropTypes.bool.isRequired,\n autoResponderMessage: PropTypes.string.isRequired,\n updateSection: PropTypes.func.isRequired,\n setParentState: PropTypes.func.isRequired,\n submit: PropTypes.func.isRequired,\n saving: PropTypes.bool.isRequired,\n error: PropTypes.string,\n };\n\n handleAutoResponderChecked = (e) => {\n this.props.setParentState('autoResponderActive', e.target.checked);\n };\n\n onMessageChanged = (e) => {\n this.props.setParentState('autoResponderMessage', e.target.value);\n };\n\n render() {\n const {\n autoResponderActive,\n autoResponderMessage,\n } = this.props;\n\n let serverError;\n if (this.props.error) {\n serverError = <label className='has-error'>{this.props.error}</label>;\n }\n\n const inputs = [];\n\n const activeToggle = (\n <div\n id='autoResponderCheckbox'\n key='autoResponderCheckbox'\n className='checkbox'\n >\n <label>\n <input\n id='autoResponderActive'\n type='checkbox'\n checked={autoResponderActive}\n onChange={this.handleAutoResponderChecked}\n />\n <FormattedMessage\n id='user.settings.notifications.autoResponderEnabled'\n defaultMessage='Enabled'\n />\n </label>\n </div>\n );\n\n const message = (\n <div\n id='autoResponderMessage'\n key='autoResponderMessage'\n >\n <div className='pt-2'>\n <AutosizeTextarea\n style={{resize: 'none'}}\n id='autoResponderMessageInput'\n className='form-control'\n rows='5'\n placeholder={localizeMessage('user.settings.notifications.autoResponderPlaceholder', 'Message')}\n value={autoResponderMessage}\n maxLength={MESSAGE_MAX_LENGTH}\n onChange={this.onMessageChanged}\n />\n {serverError}\n </div>\n </div>\n );\n\n inputs.push(activeToggle);\n if (autoResponderActive) {\n inputs.push(message);\n }\n inputs.push((\n <div\n key='autoResponderHint'\n className='mt-5'\n >\n <FormattedMessage\n id='user.settings.notifications.autoResponderHint'\n defaultMessage='Set a custom message that will be automatically sent in response to Direct Messages. Mentions in Public and Private Channels will not trigger the automated reply. Enabling Automatic Replies sets your status to Out of Office and disables email and push notifications.'\n />\n </div>\n ));\n\n return (\n <SettingItemMax\n title={\n <FormattedMessage\n id='user.settings.notifications.autoResponder'\n defaultMessage='Automatic Direct Message Replies'\n />\n }\n width='medium'\n shiftEnter={true}\n submit={this.props.submit}\n saving={this.props.saving}\n inputs={inputs}\n updateSection={this.props.updateSection}\n />\n );\n }\n}\n","// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.\n// See LICENSE.txt for license information.\n/* eslint-disable max-lines */\n\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport {FormattedMessage} from 'react-intl';\n\nimport semver from 'semver';\n\nimport Constants, {NotificationLevels} from 'utils/constants';\nimport * as Utils from 'utils/utils.jsx';\nimport SettingItemMax from 'components/setting_item_max.jsx';\nimport SettingItemMin from 'components/setting_item_min';\n\nimport {isDesktopApp} from 'utils/user_agent';\n\nimport DesktopNotificationSettings from './desktop_notification_settings.jsx';\nimport EmailNotificationSetting from './email_notification_setting';\nimport ManageAutoResponder from './manage_auto_responder.jsx';\n\nfunction getNotificationsStateFromProps(props) {\n const user = props.user;\n\n let desktop = NotificationLevels.MENTION;\n let desktopThreads = NotificationLevels.ALL;\n let pushThreads = NotificationLevels.ALL;\n let emailThreads = NotificationLevels.ALL;\n let sound = 'true';\n let desktopNotificationSound = 'Bing';\n let comments = 'never';\n let enableEmail = 'true';\n let pushActivity = NotificationLevels.MENTION;\n let pushStatus = Constants.UserStatuses.AWAY;\n let autoResponderActive = false;\n let autoResponderMessage = Utils.localizeMessage(\n 'user.settings.notifications.autoResponderDefault',\n 'Hello, I am out of office and unable to respond to messages.',\n );\n\n if (user.notify_props) {\n if (user.notify_props.desktop) {\n desktop = user.notify_props.desktop;\n }\n if (user.notify_props.desktop_threads) {\n desktopThreads = user.notify_props.desktop_threads;\n }\n if (user.notify_props.push_threads) {\n pushThreads = user.notify_props.push_threads;\n }\n if (user.notify_props.email_threads) {\n emailThreads = user.notify_props.email_threads;\n }\n if (user.notify_props.desktop_sound) {\n sound = user.notify_props.desktop_sound;\n }\n if (user.notify_props.desktop_notification_sound) {\n desktopNotificationSound = user.notify_props.desktop_notification_sound;\n }\n if (user.notify_props.comments) {\n comments = user.notify_props.comments;\n }\n if (user.notify_props.email) {\n enableEmail = user.notify_props.email;\n }\n if (user.notify_props.push) {\n pushActivity = user.notify_props.push;\n }\n if (user.notify_props.push_status) {\n pushStatus = user.notify_props.push_status;\n }\n\n if (user.notify_props.auto_responder_active) {\n autoResponderActive = user.notify_props.auto_responder_active === 'true';\n }\n\n if (user.notify_props.auto_responder_message) {\n autoResponderMessage = user.notify_props.auto_responder_message;\n }\n }\n\n let usernameKey = false;\n let customKeys = '';\n let firstNameKey = false;\n let channelKey = false;\n\n if (user.notify_props) {\n if (user.notify_props.mention_keys) {\n const keys = user.notify_props.mention_keys.split(',');\n\n if (keys.indexOf(user.username) === -1) {\n usernameKey = false;\n } else {\n usernameKey = true;\n keys.splice(keys.indexOf(user.username), 1);\n if (keys.indexOf(`@${user.username}`) !== -1) {\n keys.splice(keys.indexOf(`@${user.username}`), 1);\n }\n }\n\n customKeys = keys.join(',');\n }\n\n if (user.notify_props.first_name) {\n firstNameKey = user.notify_props.first_name === 'true';\n }\n\n if (user.notify_props.channel) {\n channelKey = user.notify_props.channel === 'true';\n }\n }\n\n return {\n desktopActivity: desktop,\n desktopThreads,\n pushThreads,\n emailThreads,\n enableEmail,\n pushActivity,\n pushStatus,\n desktopSound: sound,\n desktopNotificationSound,\n usernameKey,\n customKeys,\n customKeysChecked: customKeys.length > 0,\n firstNameKey,\n channelKey,\n autoResponderActive,\n autoResponderMessage,\n notifyCommentsLevel: comments,\n isSaving: false,\n };\n}\n\nexport default class NotificationsTab extends React.PureComponent {\n static propTypes = {\n user: PropTypes.object,\n updateSection: PropTypes.func,\n activeSection: PropTypes.string,\n closeModal: PropTypes.func.isRequired,\n collapseModal: PropTypes.func.isRequired,\n sendPushNotifications: PropTypes.bool,\n enableAutoResponder: PropTypes.bool,\n actions: PropTypes.shape({\n updateMe: PropTypes.func.isRequired,\n }).isRequired,\n isCollapsedThreadsEnabled: PropTypes.bool.isRequired,\n }\n\n static defaultProps = {\n user: null,\n activeSection: '',\n activeTab: '',\n }\n\n constructor(props) {\n super(props);\n\n this.state = getNotificationsStateFromProps(props);\n this.customCheckRef = React.createRef();\n this.customMentionsRef = React.createRef();\n this.drawerRef = React.createRef();\n this.wrapperRef = React.createRef();\n }\n\n handleSubmit = () => {\n const data = {};\n data.email = this.state.enableEmail;\n data.desktop_sound = this.state.desktopSound;\n if (!isDesktopApp() || (window.desktop && semver.gte(window.desktop.version, '4.6.0'))) {\n data.desktop_notification_sound = this.state.desktopNotificationSound;\n }\n data.desktop = this.state.desktopActivity;\n data.desktop_threads = this.state.desktopThreads;\n data.email_threads = this.state.emailThreads;\n data.push_threads = this.state.pushThreads;\n data.push = this.state.pushActivity;\n data.push_status = this.state.pushStatus;\n data.comments = this.state.notifyCommentsLevel;\n data.auto_responder_active = this.state.autoResponderActive.toString();\n data.auto_responder_message = this.state.autoResponderMessage;\n\n if (!data.auto_responder_message || data.auto_responder_message === '') {\n data.auto_responder_message = Utils.localizeMessage(\n 'user.settings.notifications.autoResponderDefault',\n 'Hello, I am out of office and unable to respond to messages.',\n );\n }\n\n const mentionKeys = [];\n if (this.state.usernameKey) {\n mentionKeys.push(this.props.user.username);\n }\n\n let stringKeys = mentionKeys.join(',');\n if (this.state.customKeys.length > 0 && this.state.customKeysChecked) {\n stringKeys += ',' + this.state.customKeys;\n }\n\n data.mention_keys = stringKeys;\n data.first_name = this.state.firstNameKey.toString();\n data.channel = this.state.channelKey.toString();\n\n this.setState({isSaving: true});\n\n this.props.actions.updateMe({notify_props: data}).\n then(({data: result, error: err}) => {\n if (result) {\n this.handleUpdateSection('');\n this.setState(getNotificationsStateFromProps(this.props));\n } else if (err) {\n this.setState({serverError: err.message, isSaving: false});\n }\n });\n }\n\n handleCancel = (e) => {\n if (e) {\n e.preventDefault();\n }\n this.setState(getNotificationsStateFromProps(this.props));\n }\n\n handleUpdateSection = (section) => {\n if (section) {\n this.props.updateSection(section);\n } else {\n this.props.updateSection('');\n }\n this.setState({isSaving: false});\n this.handleCancel();\n };\n\n setStateValue = (key, value) => {\n const data = {};\n data[key] = value;\n this.setState(data);\n }\n\n handleNotifyPushThread = (e) => {\n const pushThreads = e.target.checked ? NotificationLevels.ALL : NotificationLevels.MENTION;\n this.setState({pushThreads});\n }\n\n handleNotifyCommentsRadio(notifyCommentsLevel) {\n this.setState({notifyCommentsLevel});\n }\n\n handlePushRadio(pushActivity) {\n this.setState({pushActivity});\n }\n\n handlePushStatusRadio(pushStatus) {\n this.setState({pushStatus});\n }\n\n handleEmailRadio = (enableEmail) => {\n this.setState({enableEmail});\n }\n\n updateUsernameKey = (val) => {\n this.setState({usernameKey: val});\n }\n\n updateFirstNameKey = (val) => {\n this.setState({firstNameKey: val});\n }\n\n updateChannelKey = (val) => {\n this.setState({channelKey: val});\n }\n\n updateCustomMentionKeys = () => {\n const checked = this.customCheckRef.current.checked;\n\n if (checked) {\n const text = this.customMentionsRef.current.value;\n\n // remove all spaces and split string into individual keys\n this.setState({customKeys: text.replace(/ /g, ''), customKeysChecked: true});\n } else {\n this.setState({customKeys: '', customKeysChecked: false});\n }\n }\n\n onCustomChange = () => {\n this.customCheckRef.current.checked = true;\n this.updateCustomMentionKeys();\n }\n\n createPushNotificationSection = () => {\n if (this.props.activeSection === 'push') {\n const inputs = [];\n let submit = null;\n\n if (this.props.sendPushNotifications) {\n const pushActivityRadio = [false, false, false];\n if (this.state.pushActivity === NotificationLevels.ALL) {\n pushActivityRadio[0] = true;\n } else if (this.state.pushActivity === NotificationLevels.NONE) {\n pushActivityRadio[2] = true;\n } else {\n pushActivityRadio[1] = true;\n }\n\n const pushStatusRadio = [false, false, false];\n if (this.state.pushStatus === Constants.UserStatuses.ONLINE) {\n pushStatusRadio[0] = true;\n } else if (this.state.pushStatus === Constants.UserStatuses.AWAY) {\n pushStatusRadio[1] = true;\n } else {\n pushStatusRadio[2] = true;\n }\n\n let pushThreadsNotificationSelection = null;\n if (this.props.isCollapsedThreadsEnabled && this.state.pushActivity === NotificationLevels.MENTION) {\n pushThreadsNotificationSelection = (\n <React.Fragment key='userNotificationPushThreadsOptions'>\n <hr/>\n <fieldset>\n <legend className='form-legend'>\n <FormattedMessage\n id='user.settings.notifications.threads.desktop'\n defaultMessage='Thread reply notifications'\n />\n </legend>\n <div className='checkbox'>\n <label>\n <input\n id='desktopThreadsNotificationAllActivity'\n type='checkbox'\n name='desktopThreadsNotificationLevel'\n checked={this.state.pushThreads === NotificationLevels.ALL}\n onChange={this.handleNotifyPushThread}\n />\n <FormattedMessage\n id='user.settings.notifications.threads.allActivity'\n defaultMessage={'Notify me about threads I\\'m following'}\n />\n </label>\n <br/>\n </div>\n <div className='mt-5'>\n <FormattedMessage\n id='user.settings.notifications.threads'\n defaultMessage={'When enabled, any replies to a thread you\\'re following will send a desktop notification.'}\n />\n </div>\n </fieldset>\n </React.Fragment>\n );\n }\n let pushStatusSettings;\n if (this.state.pushActivity !== NotificationLevels.NONE) {\n pushStatusSettings = (\n <React.Fragment key='userNotificationPushStatusOptions'>\n <hr/>\n <fieldset>\n <legend className='form-legend'>\n <FormattedMessage\n id='user.settings.notifications.push_notification.status'\n defaultMessage='Trigger push notifications when'\n />\n </legend>\n <div className='radio'>\n <label>\n <input\n id='pushNotificationOnline'\n type='radio'\n name='pushNotificationStatus'\n checked={pushStatusRadio[0]}\n onChange={this.handlePushStatusRadio.bind(this, Constants.UserStatuses.ONLINE)}\n />\n <FormattedMessage\n id='user.settings.push_notification.online'\n defaultMessage='Online, away or offline'\n />\n </label>\n </div>\n <div className='radio'>\n <label>\n <input\n id='pushNotificationAway'\n type='radio'\n name='pushNotificationStatus'\n checked={pushStatusRadio[1]}\n onChange={this.handlePushStatusRadio.bind(this, Constants.UserStatuses.AWAY)}\n />\n <FormattedMessage\n id='user.settings.push_notification.away'\n defaultMessage='Away or offline'\n />\n </label>\n </div>\n <div className='radio'>\n <label>\n <input\n id='pushNotificationOffline'\n type='radio'\n name='pushNotificationStatus'\n checked={pushStatusRadio[2]}\n onChange={this.handlePushStatusRadio.bind(this, Constants.UserStatuses.OFFLINE)}\n />\n <FormattedMessage\n id='user.settings.push_notification.offline'\n defaultMessage='Offline'\n />\n </label>\n </div>\n <div className='mt-5'>\n <span>\n <FormattedMessage\n id='user.settings.push_notification.status_info'\n defaultMessage='Notification alerts are only pushed to your mobile device when your availability matches the selection above.'\n />\n </span>\n </div>\n </fieldset>\n </React.Fragment>\n );\n }\n\n inputs.push(\n <div>\n <fieldset key='userNotificationLevelOption'>\n <legend className='form-legend'>\n <FormattedMessage\n id='user.settings.push_notification.send'\n defaultMessage='Send mobile push notifications'\n />\n </legend>\n <div className='radio'>\n <label>\n <input\n id='pushNotificationAllActivity'\n type='radio'\n name='pushNotificationLevel'\n checked={pushActivityRadio[0]}\n onChange={this.handlePushRadio.bind(this, NotificationLevels.ALL)}\n />\n <FormattedMessage\n id='user.settings.push_notification.allActivity'\n defaultMessage='For all activity'\n />\n </label>\n </div>\n <div className='radio'>\n <label>\n <input\n id='pushNotificationMentions'\n type='radio'\n name='pushNotificationLevel'\n checked={pushActivityRadio[1]}\n onChange={this.handlePushRadio.bind(this, NotificationLevels.MENTION)}\n />\n <FormattedMessage\n id='user.settings.push_notification.onlyMentions'\n defaultMessage='For mentions and direct messages'\n />\n </label>\n </div>\n <div className='radio'>\n <label>\n <input\n id='pushNotificationNever'\n type='radio'\n name='pushNotificationLevel'\n checked={pushActivityRadio[2]}\n onChange={this.handlePushRadio.bind(this, NotificationLevels.NONE)}\n />\n <FormattedMessage\n id='user.settings.notifications.never'\n defaultMessage='Never'\n />\n </label>\n </div>\n <div className='mt-5'>\n <FormattedMessage\n id='user.settings.push_notification.info'\n defaultMessage='Notification alerts are pushed to your mobile device when there is activity in Mattermost.'\n />\n </div>\n </fieldset>\n </div>,\n pushStatusSettings,\n pushThreadsNotificationSelection,\n );\n\n submit = this.handleSubmit;\n } else {\n inputs.push(\n <div\n key='oauthEmailInfo'\n className='pt-2'\n >\n <FormattedMessage\n id='user.settings.push_notification.disabled_long'\n defaultMessage='Push notifications have not been enabled by your System Administrator.'\n />\n </div>,\n );\n }\n\n return (\n <SettingItemMax\n title={Utils.localizeMessage('user.settings.notifications.push', 'Mobile Push Notifications')}\n inputs={inputs}\n submit={submit}\n server_error={this.state.serverError}\n updateSection={this.handleUpdateSection}\n />\n );\n }\n\n let describe = '';\n if (this.state.pushActivity === NotificationLevels.ALL) {\n if (this.state.pushStatus === Constants.UserStatuses.AWAY) {\n describe = (\n <FormattedMessage\n id='user.settings.push_notification.allActivityAway'\n defaultMessage='For all activity when away or offline'\n />\n );\n } else if (this.state.pushStatus === Constants.UserStatuses.OFFLINE) {\n describe = (\n <FormattedMessage\n id='user.settings.push_notification.allActivityOffline'\n defaultMessage='For all activity when offline'\n />\n );\n } else {\n describe = (\n <FormattedMessage\n id='user.settings.push_notification.allActivityOnline'\n defaultMessage='For all activity when online, away or offline'\n />\n );\n }\n } else if (this.state.pushActivity === NotificationLevels.NONE) {\n describe = (\n <FormattedMessage\n id='user.settings.notifications.never'\n defaultMessage='Never'\n />\n );\n } else if (this.props.sendPushNotifications) {\n if (this.state.pushStatus === Constants.UserStatuses.AWAY) { //eslint-disable-line no-lonely-if\n describe = (\n <FormattedMessage\n id='user.settings.push_notification.onlyMentionsAway'\n defaultMessage='For mentions and direct messages when away or offline'\n />\n );\n } else if (this.state.pushStatus === Constants.UserStatuses.OFFLINE) {\n describe = (\n <FormattedMessage\n id='user.settings.push_notification.onlyMentionsOffline'\n defaultMessage='For mentions and direct messages when offline'\n />\n );\n } else {\n describe = (\n <FormattedMessage\n id='user.settings.push_notification.onlyMentionsOnline'\n defaultMessage='For mentions and direct messages when online, away or offline'\n />\n );\n }\n } else {\n describe = (\n <FormattedMessage\n id='user.settings.push_notification.disabled'\n defaultMessage='Push notifications are not enabled'\n />\n );\n }\n\n return (\n <SettingItemMin\n title={Utils.localizeMessage('user.settings.notifications.push', 'Mobile Push Notifications')}\n describe={describe}\n section={'push'}\n updateSection={this.handleUpdateSection}\n />\n );\n }\n\n render() {\n const serverError = this.state.serverError;\n const user = this.props.user;\n\n let keysSection;\n if (this.props.activeSection === 'keys') {\n const inputs = [];\n\n if (user.first_name) {\n const handleUpdateFirstNameKey = (e) => {\n this.updateFirstNameKey(e.target.checked);\n };\n inputs.push(\n <div key='userNotificationFirstNameOption'>\n <div className='checkbox'>\n <label>\n <input\n id='notificationTriggerFirst'\n type='checkbox'\n checked={this.state.firstNameKey}\n onChange={handleUpdateFirstNameKey}\n />\n <FormattedMessage\n id='user.settings.notifications.sensitiveName'\n defaultMessage='Your case sensitive first name \"{first_name}\"'\n values={{\n first_name: user.first_name,\n }}\n />\n </label>\n </div>\n </div>,\n );\n }\n\n const handleUpdateUsernameKey = (e) => {\n this.updateUsernameKey(e.target.checked);\n };\n inputs.push(\n <div key='userNotificationUsernameOption'>\n <div className='checkbox'>\n <label>\n <input\n id='notificationTriggerUsername'\n type='checkbox'\n checked={this.state.usernameKey}\n onChange={handleUpdateUsernameKey}\n />\n <FormattedMessage\n id='user.settings.notifications.sensitiveUsername'\n defaultMessage='Your non case-sensitive username \"{username}\"'\n values={{\n username: user.username,\n }}\n />\n </label>\n </div>\n </div>,\n );\n\n const handleUpdateChannelKey = (e) => {\n this.updateChannelKey(e.target.checked);\n };\n inputs.push(\n <div key='userNotificationChannelOption'>\n <div className='checkbox'>\n <label>\n <input\n id='notificationTriggerShouts'\n type='checkbox'\n checked={this.state.channelKey}\n onChange={handleUpdateChannelKey}\n />\n <FormattedMessage\n id='user.settings.notifications.channelWide'\n defaultMessage='Channel-wide mentions \"@channel\", \"@all\", \"@here\"'\n />\n </label>\n </div>\n </div>,\n );\n\n inputs.push(\n <div key='userNotificationCustomOption'>\n <div className='checkbox'>\n <label>\n <input\n id='notificationTriggerCustom'\n ref={this.customCheckRef}\n type='checkbox'\n checked={this.state.customKeysChecked}\n onChange={this.updateCustomMentionKeys}\n />\n <FormattedMessage\n id='user.settings.notifications.sensitiveWords'\n defaultMessage='Other non-case sensitive words, separated by commas:'\n />\n </label>\n </div>\n <input\n id='notificationTriggerCustomText'\n autoFocus={this.state.customKeysChecked}\n ref={this.customMentionsRef}\n className='form-control mentions-input'\n type='text'\n defaultValue={this.state.customKeys}\n onChange={this.onCustomChange}\n onFocus={Utils.moveCursorToEnd}\n aria-labelledby='notificationTriggerCustom'\n />\n </div>,\n );\n\n const extraInfo = (\n <span>\n <FormattedMessage\n id='user.settings.notifications.mentionsInfo'\n defaultMessage='Mentions trigger when someone sends a message that includes your username (@{username}) or any of the options selected above.'\n values={{\n username: user.username,\n }}\n />\n </span>\n );\n\n keysSection = (\n <SettingItemMax\n title={Utils.localizeMessage('user.settings.notifications.wordsTrigger', 'Words That Trigger Mentions')}\n inputs={inputs}\n submit={this.handleSubmit}\n saving={this.state.isSaving}\n server_error={serverError}\n updateSection={this.handleUpdateSection}\n extraInfo={extraInfo}\n />\n );\n } else {\n let keys = ['@' + user.username];\n if (this.state.firstNameKey) {\n keys.push(user.first_name);\n }\n if (this.state.usernameKey) {\n keys.push(user.username);\n }\n\n if (this.state.channelKey) {\n keys.push('@channel');\n keys.push('@all');\n keys.push('@here');\n }\n if (this.state.customKeys.length > 0) {\n keys = keys.concat(this.state.customKeys.split(','));\n }\n\n let describe = '';\n for (let i = 0; i < keys.length; i++) {\n if (keys[i] !== '') {\n describe += '\"' + keys[i] + '\", ';\n }\n }\n\n if (describe.length > 0) {\n describe = describe.substring(0, describe.length - 2);\n } else {\n describe = (\n <FormattedMessage\n id='user.settings.notifications.noWords'\n defaultMessage='No words configured'\n />\n );\n }\n\n keysSection = (\n <SettingItemMin\n title={Utils.localizeMessage('user.settings.notifications.wordsTrigger', 'Words That Trigger Mentions')}\n describe={describe}\n section={'keys'}\n updateSection={this.handleUpdateSection}\n />\n );\n }\n\n let commentsSection;\n if (this.props.activeSection === 'comments') {\n const commentsActive = [false, false, false];\n if (this.state.notifyCommentsLevel === 'never') {\n commentsActive[2] = true;\n } else if (this.state.notifyCommentsLevel === 'root') {\n commentsActive[1] = true;\n } else {\n commentsActive[0] = true;\n }\n\n const inputs = [];\n\n inputs.push(\n <fieldset key='userNotificationLevelOption'>\n <legend className='form-legend hidden-label'>\n {Utils.localizeMessage('user.settings.notifications.comments', 'Reply notifications')}\n </legend>\n <div className='radio'>\n <label>\n <input\n id='notificationCommentsAny'\n type='radio'\n name='commentsNotificationLevel'\n checked={commentsActive[0]}\n onChange={this.handleNotifyCommentsRadio.bind(this, 'any')}\n />\n <FormattedMessage\n id='user.settings.notifications.commentsAny'\n defaultMessage='Trigger notifications on messages in reply threads that I start or participate in'\n />\n </label>\n <br/>\n </div>\n <div className='radio'>\n <label>\n <input\n id='notificationCommentsRoot'\n type='radio'\n name='commentsNotificationLevel'\n checked={commentsActive[1]}\n onChange={this.handleNotifyCommentsRadio.bind(this, 'root')}\n />\n <FormattedMessage\n id='user.settings.notifications.commentsRoot'\n defaultMessage='Trigger notifications on messages in threads that I start'\n />\n </label>\n <br/>\n </div>\n <div className='radio'>\n <label>\n <input\n id='notificationCommentsNever'\n type='radio'\n name='commentsNotificationLevel'\n checked={commentsActive[2]}\n onChange={this.handleNotifyCommentsRadio.bind(this, 'never')}\n />\n <FormattedMessage\n id='user.settings.notifications.commentsNever'\n defaultMessage=\"Do not trigger notifications on messages in reply threads unless I'm mentioned\"\n />\n </label>\n </div>\n </fieldset>,\n );\n\n const extraInfo = (\n <span>\n <FormattedMessage\n id='user.settings.notifications.commentsInfo'\n defaultMessage=\"In addition to notifications for when you're mentioned, select if you would like to receive notifications on reply threads.\"\n />\n </span>\n );\n\n commentsSection = (\n <SettingItemMax\n title={Utils.localizeMessage('user.settings.notifications.comments', 'Reply notifications')}\n extraInfo={extraInfo}\n inputs={inputs}\n submit={this.handleSubmit}\n saving={this.state.isSaving}\n server_error={serverError}\n updateSection={this.handleUpdateSection}\n />\n );\n } else {\n let describe = '';\n if (this.state.notifyCommentsLevel === 'never') {\n describe = (\n <FormattedMessage\n id='user.settings.notifications.commentsNever'\n defaultMessage=\"Do not trigger notifications on messages in reply threads unless I'm mentioned\"\n />\n );\n } else if (this.state.notifyCommentsLevel === 'root') {\n describe = (\n <FormattedMessage\n id='user.settings.notifications.commentsRoot'\n defaultMessage='Trigger notifications on messages in threads that I start'\n />\n );\n } else {\n describe = (\n <FormattedMessage\n id='user.settings.notifications.commentsAny'\n defaultMessage='Trigger notifications on messages in reply threads that I start or participate in'\n />\n );\n }\n\n commentsSection = (\n <SettingItemMin\n title={Utils.localizeMessage('user.settings.notifications.comments', 'Reply notifications')}\n describe={describe}\n section={'comments'}\n updateSection={this.handleUpdateSection}\n />\n );\n }\n\n let autoResponderSection;\n if (this.props.enableAutoResponder) {\n if (this.props.activeSection === 'auto-responder') {\n autoResponderSection = (\n <div>\n <ManageAutoResponder\n autoResponderActive={this.state.autoResponderActive}\n autoResponderMessage={this.state.autoResponderMessage}\n updateSection={this.handleUpdateSection}\n setParentState={this.setStateValue}\n submit={this.handleSubmit}\n error={this.state.serverError}\n saving={this.state.isSaving}\n />\n <div className='divider-dark'/>\n </div>\n );\n } else {\n const describe = this.state.autoResponderActive ? (\n <FormattedMessage\n id='user.settings.notifications.autoResponderEnabled'\n defaultMessage='Enabled'\n />\n ) : (\n <FormattedMessage\n id='user.settings.notifications.autoResponderDisabled'\n defaultMessage='Disabled'\n />\n );\n\n autoResponderSection = (\n <SettingItemMin\n title={\n <FormattedMessage\n id='user.settings.notifications.autoResponder'\n defaultMessage='Automatic Direct Message Replies'\n />\n }\n width='medium'\n describe={describe}\n section={'auto-responder'}\n updateSection={this.handleUpdateSection}\n />\n );\n }\n }\n\n const pushNotificationSection = this.createPushNotificationSection();\n\n return (\n <div id='notificationSettings'>\n <div className='modal-header'>\n <button\n id='closeButton'\n type='button'\n className='close'\n data-dismiss='modal'\n onClick={this.props.closeModal}\n >\n <span aria-hidden='true'>{'×'}</span>\n </button>\n <h4\n className='modal-title'\n ref={this.drawerRef}\n >\n <div className='modal-back'>\n <FormattedMessage\n id='generic_icons.collapse'\n defaultMessage='Collapse Icon'\n >\n {(title) => (\n <i\n className='fa fa-angle-left'\n title={title}\n onClick={this.props.collapseModal}\n />\n )}\n </FormattedMessage>\n </div>\n <FormattedMessage\n id='user.settings.notifications.title'\n defaultMessage='Notification Settings'\n />\n </h4>\n </div>\n <div\n ref={this.wrapperRef}\n className='user-settings'\n >\n <h3\n id='notificationSettingsTitle'\n className='tab-header'\n >\n <FormattedMessage\n id='user.settings.notifications.header'\n defaultMessage='Notifications'\n />\n </h3>\n <div className='divider-dark first'/>\n <DesktopNotificationSettings\n activity={this.state.desktopActivity}\n threads={this.state.desktopThreads}\n sound={this.state.desktopSound}\n updateSection={this.handleUpdateSection}\n setParentState={this.setStateValue}\n submit={this.handleSubmit}\n saving={this.state.isSaving}\n cancel={this.handleCancel}\n error={this.state.serverError}\n active={this.props.activeSection === 'desktop'}\n selectedSound={this.state.desktopNotificationSound}\n isCollapsedThreadsEnabled={this.props.isCollapsedThreadsEnabled}\n />\n <div className='divider-light'/>\n <EmailNotificationSetting\n activeSection={this.props.activeSection}\n updateSection={this.handleUpdateSection}\n enableEmail={this.state.enableEmail === 'true'}\n onSubmit={this.handleSubmit}\n onCancel={this.handleCancel}\n onChange={this.handleEmailRadio}\n saving={this.state.isSaving}\n serverError={this.state.serverError}\n isCollapsedThreadsEnabled={this.props.isCollapsedThreadsEnabled}\n setParentState={this.setStateValue}\n threads={this.state.emailThreads}\n />\n <div className='divider-light'/>\n {pushNotificationSection}\n <div className='divider-light'/>\n {keysSection}\n <div className='divider-light'/>\n {!this.props.isCollapsedThreadsEnabled && (\n <>\n {commentsSection}\n <div className='divider-light'/>\n </>\n )}\n {autoResponderSection}\n <div className='divider-dark'/>\n </div>\n </div>\n\n );\n }\n}\n/* eslint-enable react/no-string-refs */\n","// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.\n// See LICENSE.txt for license information.\n\nimport {connect} from 'react-redux';\nimport {bindActionCreators} from 'redux';\n\nimport {updateMe} from 'mattermost-redux/actions/users';\nimport {getConfig} from 'mattermost-redux/selectors/entities/general';\nimport {isCollapsedThreadsEnabled} from 'mattermost-redux/selectors/entities/preferences';\n\nimport UserSettingsNotifications from './user_settings_notifications.jsx';\n\nfunction mapStateToProps(state) {\n const config = getConfig(state);\n\n const sendPushNotifications = config.SendPushNotifications === 'true';\n const enableAutoResponder = config.ExperimentalEnableAutomaticReplies === 'true';\n\n return {\n sendPushNotifications,\n enableAutoResponder,\n isCollapsedThreadsEnabled: isCollapsedThreadsEnabled(state),\n };\n}\n\nfunction mapDispatchToProps(dispatch) {\n return {\n actions: bindActionCreators({updateMe}, dispatch),\n };\n}\n\nexport default connect(mapStateToProps, mapDispatchToProps)(UserSettingsNotifications);\n","// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.\n// See LICENSE.txt for license information.\n\nimport React from 'react';\nimport {Modal} from 'react-bootstrap';\nimport {FormattedMessage} from 'react-intl';\n\nimport AuditTable from 'components/audit_table';\nimport LoadingScreen from 'components/loading_screen';\n\ntype Props = {\n onHide: () => void;\n actions: {\n getUserAudits: (userId: string, page?: number, perPage?: number) => void;\n };\n userAudits: any[];\n currentUserId: string;\n}\n\ntype State = {\n show: boolean;\n}\n\nexport default class AccessHistoryModal extends React.PureComponent<Props, State> {\n public constructor(props: Props) {\n super(props);\n\n this.state = {\n show: true,\n };\n }\n\n public onShow = () => { // public for testing\n this.props.actions.getUserAudits(this.props.currentUserId, 0, 200);\n }\n\n public onHide = () => { // public for testing\n this.setState({show: false});\n }\n\n public componentDidMount() {\n this.onShow();\n }\n\n public render() {\n let content;\n if (this.props.userAudits.length === 0) {\n content = (<LoadingScreen/>);\n } else {\n content = (\n <AuditTable\n audits={this.props.userAudits}\n showIp={true}\n showSession={true}\n />\n );\n }\n\n return (\n <Modal\n dialogClassName='a11y__modal modal--scroll'\n show={this.state.show}\n onHide={this.onHide}\n onExited={this.props.onHide}\n bsSize='large'\n role='dialog'\n aria-labelledby='accessHistoryModalLabel'\n >\n <Modal.Header closeButton={true}>\n <Modal.Title\n componentClass='h1'\n id='accessHistoryModalLabel'\n >\n <FormattedMessage\n id='access_history.title'\n defaultMessage='Access History'\n />\n </Modal.Title>\n </Modal.Header>\n <Modal.Body>\n {content}\n </Modal.Body>\n <Modal.Footer className='modal-footer--invisible'>\n <button\n id='closeModalButton'\n type='button'\n className='btn btn-link'\n >\n <FormattedMessage\n id='general_button.close'\n defaultMessage='Close'\n />\n </button>\n </Modal.Footer>\n </Modal>\n );\n }\n}\n","// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.\n// See LICENSE.txt for license information.\n\nimport {connect} from 'react-redux';\nimport {bindActionCreators, Dispatch} from 'redux';\n\nimport {getUserAudits} from 'mattermost-redux/actions/users';\nimport {getCurrentUserId, getUserAudits as getCurrentUserAudits} from 'mattermost-redux/selectors/entities/users';\nimport {GenericAction} from 'mattermost-redux/types/actions';\n\nimport {GlobalState} from 'types/store';\n\nimport AccessHistoryModal from './access_history_modal';\n\nfunction mapStateToProps(state: GlobalState) {\n return {\n currentUserId: getCurrentUserId(state),\n userAudits: getCurrentUserAudits(state) || [],\n };\n}\n\nfunction mapDispatchToProps(dispatch: Dispatch<GenericAction>) {\n return {\n actions: bindActionCreators({\n getUserAudits,\n }, dispatch),\n };\n}\n\nexport default connect(mapStateToProps, mapDispatchToProps)(AccessHistoryModal);\n","// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.\n// See LICENSE.txt for license information.\n\nimport React from 'react';\nimport {FormattedDate, FormattedMessage, FormattedTime} from 'react-intl';\n\nimport {Session} from 'mattermost-redux/types/sessions';\n\nimport {getMonthLong} from 'utils/i18n';\n\ntype Props = {\n locale: string;\n currentSession: Session;\n handleMoreInfo: () => void;\n moreInfo: boolean;\n};\n\nexport default function MoreInfo(props: Props) {\n const {locale, currentSession, handleMoreInfo, moreInfo} = props;\n\n if (moreInfo) {\n const firstAccessTime = new Date(currentSession.create_at);\n\n return (\n <div>\n <div>\n <FormattedMessage\n id='activity_log.firstTime'\n defaultMessage='First time active: {date}, {time}'\n values={{\n date: (\n <FormattedDate\n value={firstAccessTime}\n day='2-digit'\n month={getMonthLong(locale)}\n year='numeric'\n />\n ),\n time: (\n <FormattedTime\n value={firstAccessTime}\n hour='2-digit'\n minute='2-digit'\n />\n ),\n }}\n />\n </div>\n <div>\n <FormattedMessage\n id='activity_log.os'\n defaultMessage='OS: {os}'\n values={{\n os: currentSession.props.os,\n }}\n />\n </div>\n <div>\n <FormattedMessage\n id='activity_log.browser'\n defaultMessage='Browser: {browser}'\n values={{\n browser: currentSession.props.browser,\n }}\n />\n </div>\n <div>\n <FormattedMessage\n id='activity_log.sessionId'\n defaultMessage='Session ID: {id}'\n values={{\n id: currentSession.id,\n }}\n />\n </div>\n </div>\n );\n }\n\n return (\n <a\n className='theme'\n href='#'\n onClick={handleMoreInfo}\n >\n <FormattedMessage\n id='activity_log.moreInfo'\n defaultMessage='More info'\n />\n </a>\n );\n}\n","// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.\n// See LICENSE.txt for license information.\n\nimport React from 'react';\nimport {FormattedDate, FormattedMessage, FormattedTime} from 'react-intl';\n\nimport {General} from 'mattermost-redux/constants';\nimport {Session} from 'mattermost-redux/types/sessions';\n\nimport {localizeMessage} from 'utils/utils.jsx';\nimport {getMonthLong, t} from 'utils/i18n';\n\nimport MoreInfo from './more_info';\n\ntype Props = {\n\n /**\n * The index of this instance within the list\n */\n index: number;\n\n /**\n * The current locale of the user\n */\n locale: string;\n\n /**\n * The session that's to be displayed\n */\n currentSession: Session;\n\n /**\n * Function to revoke session\n */\n submitRevoke: (sessionId: string, event: React.MouseEvent) => void;\n};\n\ntype State = {\n moreInfo: boolean;\n};\n\ntype MobileSessionInfo = {\n devicePicture?: string;\n deviceTitle?: string;\n devicePlatform: JSX.Element;\n};\n\nexport default class ActivityLog extends React.PureComponent<Props, State> {\n constructor(props: Props) {\n super(props);\n\n this.state = {\n moreInfo: false,\n };\n }\n\n handleMoreInfo = (): void => {\n this.setState({moreInfo: true});\n }\n\n submitRevoke = (e: React.MouseEvent): void => {\n this.props.submitRevoke(this.props.currentSession.id, e);\n }\n\n isMobileSession = (session: Session): boolean => {\n return Boolean(session.device_id && (session.device_id.includes('apple') || session.device_id.includes('android')));\n };\n\n mobileSessionInfo = (session: Session): MobileSessionInfo => {\n let deviceTypeId;\n let deviceTypeMessage;\n let devicePicture;\n let deviceTitle;\n\n if (session.device_id.includes('apple')) {\n devicePicture = 'fa fa-apple';\n deviceTitle = localizeMessage('device_icons.apple', 'Apple Icon');\n deviceTypeId = t('activity_log_modal.iphoneNativeClassicApp');\n deviceTypeMessage = 'iPhone Native Classic App';\n\n if (session.device_id.includes(General.PUSH_NOTIFY_APPLE_REACT_NATIVE)) {\n deviceTypeId = t('activity_log_modal.iphoneNativeApp');\n deviceTypeMessage = 'iPhone Native App';\n }\n } else if (session.device_id.includes('android')) {\n devicePicture = 'fa fa-android';\n deviceTitle = localizeMessage('device_icons.android', 'Android Icon');\n deviceTypeId = t('activity_log_modal.androidNativeClassicApp');\n deviceTypeMessage = 'Android Native Classic App';\n\n if (session.device_id.includes(General.PUSH_NOTIFY_ANDROID_REACT_NATIVE)) {\n deviceTypeId = t('activity_log_modal.androidNativeApp');\n deviceTypeMessage = 'Android Native App';\n }\n }\n\n return {\n devicePicture,\n deviceTitle,\n devicePlatform: (\n <FormattedMessage\n id={deviceTypeId}\n defaultMessage={deviceTypeMessage}\n />\n ),\n };\n };\n\n render(): React.ReactNode {\n const {\n index,\n locale,\n currentSession,\n } = this.props;\n\n const lastAccessTime = new Date(currentSession.last_activity_at);\n let devicePlatform = currentSession.props.platform;\n let devicePicture: string | undefined = '';\n let deviceTitle = '';\n\n if (currentSession.props.platform === 'Windows') {\n devicePicture = 'fa fa-windows';\n deviceTitle = localizeMessage('device_icons.windows', 'Windows Icon');\n } else if (this.isMobileSession(currentSession)) {\n const sessionInfo = this.mobileSessionInfo(currentSession);\n devicePicture = sessionInfo.devicePicture;\n devicePlatform = sessionInfo.devicePlatform;\n } else if (currentSession.props.platform === 'Macintosh' ||\n currentSession.props.platform === 'iPhone') {\n devicePicture = 'fa fa-apple';\n deviceTitle = localizeMessage('device_icons.apple', 'Apple Icon');\n } else if (currentSession.props.platform === 'Linux') {\n if (currentSession.props.os.indexOf('Android') >= 0) {\n devicePlatform = (\n <FormattedMessage\n id='activity_log_modal.android'\n defaultMessage='Android'\n />\n );\n devicePicture = 'fa fa-android';\n deviceTitle = localizeMessage('device_icons.android', 'Android Icon');\n } else {\n devicePicture = 'fa fa-linux';\n deviceTitle = localizeMessage('device_icons.linux', 'Linux Icon');\n }\n } else if (currentSession.props.os.indexOf('Linux') !== -1) {\n devicePicture = 'fa fa-linux';\n deviceTitle = localizeMessage('device_icons.linux', 'Linux Icon');\n }\n\n if (currentSession.props.browser.indexOf('Desktop App') !== -1) {\n devicePlatform = (\n <FormattedMessage\n id='activity_log_modal.desktop'\n defaultMessage='Native Desktop App'\n />\n );\n }\n\n return (\n <div\n key={'activityLogEntryKey' + index}\n className='activity-log__table'\n >\n <div className='activity-log__report'>\n <div className='report__platform'>\n <i\n className={devicePicture}\n title={deviceTitle}\n />{devicePlatform}\n </div>\n <div className='report__info'>\n <div>\n <FormattedMessage\n id='activity_log.lastActivity'\n defaultMessage='Last activity: {date}, {time}'\n values={{\n date: (\n <FormattedDate\n value={lastAccessTime}\n day='2-digit'\n month={getMonthLong(locale)}\n year='numeric'\n />\n ),\n time: (\n <FormattedTime\n value={lastAccessTime}\n hour='2-digit'\n minute='2-digit'\n />\n ),\n }}\n />\n </div>\n <MoreInfo\n locale={locale}\n currentSession={currentSession}\n moreInfo={this.state.moreInfo}\n handleMoreInfo={this.handleMoreInfo}\n />\n </div>\n </div>\n <div className='activity-log__action'>\n <button\n onClick={this.submitRevoke}\n className='btn btn-primary'\n >\n <FormattedMessage\n id='activity_log.logout'\n defaultMessage='Log Out'\n />\n </button>\n </div>\n </div>\n );\n }\n}\n","// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.\n// See LICENSE.txt for license information.\n\nimport $ from 'jquery';\nimport React from 'react';\nimport {Modal} from 'react-bootstrap';\nimport {FormattedMessage} from 'react-intl';\n\nimport {Session} from 'mattermost-redux/types/sessions';\nimport {ActionFunc} from 'mattermost-redux/types/actions';\n\nimport ActivityLog from 'components/activity_log_modal/components/activity_log';\n\nexport type Props = {\n\n /**\n * The current user id\n */\n currentUserId: string;\n\n /**\n * Current user's sessions\n */\n sessions: Session[];\n\n /**\n * Current user's locale\n */\n locale: string;\n\n /**\n * Function that's called when user closes the modal\n */\n onHide: () => void;\n\n actions: {\n\n /**\n * Function to refresh sessions from server\n */\n getSessions: (userId: string) => ActionFunc;\n\n /**\n * Function to revoke a particular session\n */\n revokeSession: (userId: string, sessionId: string) => Promise<{ data: boolean }>;\n };\n}\n\ntype State = {\n show: boolean;\n}\n\nexport default class ActivityLogModal extends React.PureComponent<Props, State> {\n static propTypes = {\n\n }\n\n constructor(props: Props) {\n super(props);\n\n this.state = {\n show: true,\n };\n }\n\n submitRevoke = (altId: string, e: React.MouseEvent) => {\n e.preventDefault();\n const modalContent = $(e.target).closest('.modal-content'); // eslint-disable-line jquery/no-closest\n modalContent.addClass('animation--highlight');\n setTimeout(() => {\n modalContent.removeClass('animation--highlight');\n }, 1500);\n this.props.actions.revokeSession(this.props.currentUserId, altId).then(() => {\n this.props.actions.getSessions(this.props.currentUserId);\n });\n }\n\n onShow = () => {\n this.props.actions.getSessions(this.props.currentUserId);\n }\n\n onHide = () => {\n this.setState({show: false});\n }\n\n componentDidMount() {\n this.onShow();\n }\n\n render() {\n const activityList = this.props.sessions.reduce((array: JSX.Element[], currentSession, index) => {\n if (currentSession.props.type === 'UserAccessToken') {\n return array;\n }\n\n array.push(\n <ActivityLog\n key={currentSession.id}\n index={index}\n locale={this.props.locale}\n currentSession={currentSession}\n submitRevoke={this.submitRevoke}\n />,\n );\n return array;\n }, []);\n\n const content = <form role='form'>{activityList}</form>;\n\n return (\n <Modal\n dialogClassName='a11y__modal modal--scroll'\n show={this.state.show}\n onHide={this.onHide}\n onExited={this.props.onHide}\n bsSize='large'\n role='dialog'\n aria-labelledby='activityLogModalLabel'\n >\n <Modal.Header closeButton={true}>\n <Modal.Title\n componentClass='h1'\n id='activityLogModalLabel'\n >\n <FormattedMessage\n id='activity_log.activeSessions'\n defaultMessage='Active Sessions'\n />\n </Modal.Title>\n </Modal.Header>\n <Modal.Body>\n <p className='session-help-text'>\n <FormattedMessage\n id='activity_log.sessionsDescription'\n defaultMessage=\"Sessions are created when you log in through a new browser on a device. Sessions let you use Mattermost without having to log in again for a time period specified by the system administrator. To end the session sooner, use the 'Log Out' button.\"\n />\n </p>\n {content}\n </Modal.Body>\n <Modal.Footer className='modal-footer--invisible'>\n <button\n id='closeModalButton'\n type='button'\n className='btn btn-link'\n >\n <FormattedMessage\n id='general_button.close'\n defaultMessage='Close'\n />\n </button>\n </Modal.Footer>\n </Modal>\n );\n }\n}\n","// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.\n// See LICENSE.txt for license information.\n\nimport {connect} from 'react-redux';\nimport {ActionCreatorsMapObject, bindActionCreators, Dispatch} from 'redux';\n\nimport {getSessions, revokeSession} from 'mattermost-redux/actions/users';\nimport {getCurrentUserId, getUserSessions} from 'mattermost-redux/selectors/entities/users';\nimport {ActionFunc, GenericAction} from 'mattermost-redux/types/actions';\n\nimport {getCurrentLocale} from 'selectors/i18n';\nimport {GlobalState} from 'types/store';\n\nimport ActivityLogModal, {Props} from './activity_log_modal';\n\nfunction mapStateToProps(state: GlobalState) {\n return {\n currentUserId: getCurrentUserId(state),\n sessions: getUserSessions(state),\n locale: getCurrentLocale(state),\n };\n}\n\nfunction mapDispatchToProps(dispatch: Dispatch<GenericAction>) {\n return {\n actions: bindActionCreators<ActionCreatorsMapObject<ActionFunc| GenericAction>, Props['actions']>({\n getSessions,\n revokeSession,\n }, dispatch),\n };\n}\n\nexport default connect(mapStateToProps, mapDispatchToProps)(ActivityLogModal);\n","// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.\n// See LICENSE.txt for license information.\n\nimport React from 'react';\nimport {FormattedMessage} from 'react-intl';\n\nimport SettingItemMax from 'components/setting_item_max';\nimport SettingItemMin from 'components/setting_item_min';\nimport {browserHistory} from 'utils/browser_history';\n\nconst SECTION_MFA = 'mfa';\n\ntype Props = {\n active: boolean;\n\n // Whether or not the current user has MFA enabled\n mfaActive: boolean;\n\n // Whether or not the current user can enable MFA based on their authentication type and the server's settings\n mfaAvailable: boolean;\n\n // Whether or not this server enforces that all users have MFA\n mfaEnforced: boolean;\n\n updateSection: (section: string) => void;\n actions: {deactivateMfa: () => Promise<{error?: {message: string}}>};\n}\n\ntype State = {\n serverError: string|null;\n}\n\nexport default class MfaSection extends React.PureComponent<Props, State> {\n public constructor(props: Props) {\n super(props);\n this.state = {\n serverError: null,\n };\n }\n\n public setupMfa = (e: React.MouseEvent<HTMLElement>) => {\n e.preventDefault();\n\n browserHistory.push('/mfa/setup');\n };\n\n public removeMfa = async (e: React.MouseEvent<HTMLElement>) => {\n e.preventDefault();\n\n const {error} = await this.props.actions.deactivateMfa();\n\n if (error) {\n this.setState({\n serverError: error.message,\n });\n return;\n }\n\n if (this.props.mfaEnforced) {\n browserHistory.push('/mfa/setup');\n return;\n }\n\n this.props.updateSection('');\n this.setState({\n serverError: null,\n });\n };\n\n private renderTitle = () => {\n return (\n <FormattedMessage\n id='user.settings.mfa.title'\n defaultMessage='Multi-factor Authentication'\n />\n );\n };\n\n private renderDescription = () => {\n if (this.props.mfaActive) {\n return (\n <FormattedMessage\n id='user.settings.security.active'\n defaultMessage='Active'\n />\n );\n }\n\n return (\n <FormattedMessage\n id='user.settings.security.inactive'\n defaultMessage='Inactive'\n />\n );\n };\n\n private renderContent = () => {\n let content;\n\n if (this.props.mfaActive) {\n let buttonText;\n\n if (this.props.mfaEnforced) {\n buttonText = (\n <FormattedMessage\n id='user.settings.mfa.reset'\n defaultMessage='Reset MFA on Account'\n />\n );\n } else {\n buttonText = (\n <FormattedMessage\n id='user.settings.mfa.remove'\n defaultMessage='Remove MFA from Account'\n />\n );\n }\n\n content = (\n <a\n className='btn btn-primary'\n href='#'\n onClick={this.removeMfa}\n >\n {buttonText}\n </a>\n );\n } else {\n content = (\n <a\n className='btn btn-primary'\n href='#'\n onClick={this.setupMfa}\n >\n <FormattedMessage\n id='user.settings.mfa.add'\n defaultMessage='Add MFA to Account'\n />\n </a>\n );\n }\n\n return (\n <div className='pt-2'>\n {content}\n <br/>\n </div>\n );\n };\n\n private renderHelpText = () => {\n if (this.props.mfaActive) {\n if (this.props.mfaEnforced) {\n return (\n <FormattedMessage\n id='user.settings.mfa.requiredHelp'\n defaultMessage='Multi-factor authentication is required on this server. Resetting is only recommended when you need to switch code generation to a new mobile device. You will be required to set it up again immediately.'\n />\n );\n }\n\n return (\n <FormattedMessage\n id='user.settings.mfa.removeHelp'\n defaultMessage='Removing multi-factor authentication means you will no longer require a phone-based passcode to sign-in to your account.'\n />\n );\n }\n\n return (\n <FormattedMessage\n id='user.settings.mfa.addHelp'\n defaultMessage='Adding multi-factor authentication will make your account more secure by requiring a code from your mobile phone each time you sign in.'\n />\n );\n };\n\n public render() {\n const title = this.renderTitle();\n\n if (!this.props.mfaAvailable) {\n return null;\n }\n\n if (!this.props.active) {\n return (\n <SettingItemMin\n title={title}\n describe={this.renderDescription()}\n section={SECTION_MFA}\n updateSection={this.props.updateSection}\n />\n );\n }\n\n return (\n <SettingItemMax\n title={title}\n inputs={this.renderContent()}\n extraInfo={this.renderHelpText()}\n serverError={this.state.serverError}\n updateSection={this.props.updateSection}\n width='medium'\n />\n );\n }\n}\n","// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.\n// See LICENSE.txt for license information.\n\nimport {connect} from 'react-redux';\nimport {bindActionCreators, Dispatch, ActionCreatorsMapObject} from 'redux';\n\nimport {getConfig, getLicense} from 'mattermost-redux/selectors/entities/general';\nimport {getCurrentUser} from 'mattermost-redux/selectors/entities/users';\nimport {GlobalState} from 'mattermost-redux/types/store';\nimport {UserProfile} from 'mattermost-redux/types/users';\nimport {ActionFunc} from 'mattermost-redux/types/actions';\n\nimport {deactivateMfa} from 'actions/views/mfa';\nimport Constants from 'utils/constants';\n\nimport MfaSection from './mfa_section';\n\ntype Actions = {\n deactivateMfa: () => Promise<{error?: {message: string}}>;\n}\n\nfunction mapStateToProps(state: GlobalState) {\n const license = getLicense(state);\n const config = getConfig(state);\n const mfaLicensed = license && license.IsLicensed === 'true' && license.MFA === 'true';\n const mfaEnabled = config.EnableMultifactorAuthentication === 'true';\n const mfaEnforced = mfaLicensed && config.EnforceMultifactorAuthentication === 'true';\n const user: UserProfile = getCurrentUser(state);\n let mfaActive = false;\n let mfaAvailable = false;\n if (user) {\n mfaActive = (user as any).mfa_active;\n mfaAvailable = mfaEnabled && (user.auth_service === '' || user.auth_service === Constants.LDAP_SERVICE);\n }\n return {\n mfaActive,\n mfaAvailable,\n mfaEnforced,\n };\n}\n\nfunction mapDispatchToProps(dispatch: Dispatch) {\n return {\n actions: bindActionCreators<ActionCreatorsMapObject<ActionFunc>, Actions>({\n deactivateMfa,\n }, dispatch),\n };\n}\n\nexport default connect(mapStateToProps, mapDispatchToProps)(MfaSection);\n","// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.\n// See LICENSE.txt for license information.\n\nimport React from 'react';\nimport {FormattedMessage} from 'react-intl';\n\nimport * as UserUtils from 'mattermost-redux/utils/user_utils';\nimport {UserProfile} from 'mattermost-redux/types/users';\n\nimport {trackEvent} from 'actions/telemetry_actions.jsx';\nimport Constants from 'utils/constants';\nimport {isMobile} from 'utils/user_agent';\nimport * as Utils from 'utils/utils.jsx';\nimport ConfirmModal from 'components/confirm_modal';\nimport SettingItemMax from 'components/setting_item_max.jsx';\nimport SettingItemMin from 'components/setting_item_min';\nimport SaveButton from 'components/save_button';\n\nimport FormattedMarkdownMessage from 'components/formatted_markdown_message.jsx';\nimport WarningIcon from 'components/widgets/icons/fa_warning_icon';\n\nconst SECTION_TOKENS = 'tokens';\nconst TOKEN_CREATING = 'creating';\nconst TOKEN_CREATED = 'created';\nconst TOKEN_NOT_CREATING = 'not_creating';\n\ntype Props = {\n user: UserProfile;\n active?: boolean;\n updateSection: (section: string) => void;\n userAccessTokens: {[tokenId: string]: {description: string; id: string; is_active: boolean}};\n setRequireConfirm: (isRequiredConfirm: boolean, confirmCopyToken: (confirmAction: () => void) => void) => void;\n actions: {\n getUserAccessTokensForUser: (userId: string, page: number, perPage: number) => void;\n createUserAccessToken: (userId: string, description: string) => Promise<{\n data: {token: string; description: string; id: string; is_active: boolean} | null;\n error?: {\n message: string;\n };\n }>;\n revokeUserAccessToken: (tokenId: string) => Promise<{\n data: string;\n error?: {\n message: string;\n };\n }>;\n enableUserAccessToken: (tokenId: string) => Promise<{\n data: string;\n error?: {\n message: string;\n };\n }>;\n disableUserAccessToken: (tokenId: string) => Promise<{\n data: string;\n error?: {\n message: string;\n };\n }>;\n clearUserAccessTokens: () => void;\n };\n}\n\ntype State = {\n active?: boolean;\n showConfirmModal: boolean;\n newToken?: {token: string; description: string; id: string; is_active: boolean} | null;\n tokenCreationState?: string;\n tokenError?: string;\n serverError?: string|null;\n saving?: boolean;\n confirmTitle?: React.ReactNode;\n confirmMessage?: ((state: State) => JSX.Element)|null;\n confirmButton?: React.ReactNode;\n confirmComplete?: (() => void)|null;\n confirmHideCancel?: boolean;\n}\n\nexport default class UserAccessTokenSection extends React.PureComponent<Props, State> {\n private newtokendescriptionRef: React.RefObject<HTMLInputElement>;\n\n constructor(props: Props) {\n super(props);\n\n this.state = {\n active: this.props.active,\n showConfirmModal: false,\n newToken: null,\n tokenCreationState: TOKEN_NOT_CREATING,\n tokenError: '',\n serverError: null,\n saving: false,\n };\n this.newtokendescriptionRef = React.createRef();\n }\n\n componentDidMount() {\n this.props.actions.clearUserAccessTokens();\n const userId = this.props.user ? this.props.user.id : '';\n this.props.actions.getUserAccessTokensForUser(userId, 0, 200);\n }\n\n static getDerivedStateFromProps(nextProps: Props, prevState: State) {\n if (!nextProps.active && prevState.active) {\n return {\n active: nextProps.active,\n showConfirmModal: false,\n newToken: null,\n tokenCreationState: TOKEN_NOT_CREATING,\n tokenError: '',\n serverError: null,\n saving: false,\n };\n }\n return {active: nextProps.active};\n }\n\n startCreatingToken = () => {\n this.setState({tokenCreationState: TOKEN_CREATING});\n }\n\n stopCreatingToken = () => {\n this.setState({tokenCreationState: TOKEN_NOT_CREATING, saving: false});\n }\n\n handleCreateToken = async () => {\n this.handleCancelConfirm();\n\n const description = this.newtokendescriptionRef ? this.newtokendescriptionRef.current!.value : '';\n\n if (description === '') {\n this.setState({tokenError: Utils.localizeMessage('user.settings.tokens.nameRequired', 'Please enter a description.')});\n return;\n }\n\n this.setState({tokenError: '', saving: true});\n this.props.setRequireConfirm(true, this.confirmCopyToken);\n\n const userId = this.props.user ? this.props.user.id : '';\n const {data, error} = await this.props.actions.createUserAccessToken(userId, description);\n\n if (data && this.state.tokenCreationState === TOKEN_CREATING) {\n this.setState({tokenCreationState: TOKEN_CREATED, newToken: data, saving: false});\n } else if (error) {\n this.setState({serverError: error.message, saving: false});\n }\n }\n\n confirmCopyToken = (confirmAction: () => void) => {\n this.setState({\n showConfirmModal: true,\n confirmTitle: (\n <FormattedMessage\n id='user.settings.tokens.confirmCopyTitle'\n defaultMessage='Copied Your Token?'\n />\n ),\n confirmMessage: (state: State) => (\n <div>\n <FormattedMessage\n id='user.settings.tokens.confirmCopyMessage'\n defaultMessage=\"Make sure you have copied and saved the access token below. You won't be able to see it again!\"\n />\n <br/>\n <br/>\n {state.tokenCreationState === TOKEN_CREATING ? (\n <div>\n <strong className='word-break--all'>\n <FormattedMessage\n id='user.settings.tokens.token'\n defaultMessage='Access Token: '\n />\n </strong>\n <FormattedMessage\n id='user.settings.tokens.tokenLoading'\n defaultMessage='Loading...'\n />\n </div>\n ) : (\n <strong className='word-break--all'>\n <FormattedMessage\n id='user.settings.tokens.token'\n defaultMessage='Access Token: '\n />\n {state.newToken!.token}\n </strong>\n )}\n </div>\n ),\n confirmButton: (\n <FormattedMessage\n id='user.settings.tokens.confirmCopyButton'\n defaultMessage='Yes, I have copied the token'\n />\n ),\n confirmComplete: () => {\n this.handleCancelConfirm();\n confirmAction();\n },\n confirmHideCancel: true,\n });\n }\n\n handleCancelConfirm = () => {\n this.setState({\n showConfirmModal: false,\n confirmTitle: null,\n confirmMessage: null,\n confirmButton: null,\n confirmComplete: null,\n confirmHideCancel: false,\n });\n }\n\n confirmCreateToken = () => {\n if (!UserUtils.isSystemAdmin(this.props.user!.roles)) {\n this.handleCreateToken();\n return;\n }\n\n this.setState({\n showConfirmModal: true,\n confirmTitle: (\n <FormattedMessage\n id='user.settings.tokens.confirmCreateTitle'\n defaultMessage='Create System Admin Personal Access Token'\n />\n ),\n confirmMessage: () => (\n <div className='alert alert-danger'>\n <FormattedMessage\n id='user.settings.tokens.confirmCreateMessage'\n defaultMessage='You are generating a personal access token with System Admin permissions. Are you sure want to create this token?'\n />\n </div>\n ),\n confirmButton: (\n <FormattedMessage\n id='user.settings.tokens.confirmCreateButton'\n defaultMessage='Yes, Create'\n />\n ),\n confirmComplete: () => {\n this.handleCreateToken();\n trackEvent('settings', 'system_admin_create_user_access_token');\n },\n });\n }\n\n saveTokenKeyPress = (e: React.KeyboardEvent) => {\n if (Utils.isKeyPressed(e, Constants.KeyCodes.ENTER)) {\n this.confirmCreateToken();\n }\n }\n\n confirmRevokeToken = (tokenId: string) => {\n const token = this.props.userAccessTokens[tokenId];\n\n this.setState({\n showConfirmModal: true,\n confirmTitle: (\n <FormattedMessage\n id='user.settings.tokens.confirmDeleteTitle'\n defaultMessage='Delete Token?'\n />\n ),\n confirmMessage: () => (\n <div className='alert alert-danger'>\n <FormattedMarkdownMessage\n id='user.settings.tokens.confirmDeleteMessage'\n defaultMessage='Any integrations using this token will no longer be able to access the Mattermost API. You cannot undo this action. \\n \\nAre you sure want to delete the **{description}** token?'\n values={{\n description: token.description,\n }}\n />\n </div>\n ),\n confirmButton: (\n <FormattedMessage\n id='user.settings.tokens.confirmDeleteButton'\n defaultMessage='Yes, Delete'\n />\n ),\n confirmComplete: () => {\n this.revokeToken(tokenId);\n trackEvent('settings', 'revoke_user_access_token');\n },\n });\n }\n\n revokeToken = async (tokenId: string) => {\n const {error} = await this.props.actions.revokeUserAccessToken(tokenId);\n if (error) {\n this.setState({serverError: error.message});\n }\n this.handleCancelConfirm();\n }\n\n activateToken = async (tokenId: string) => {\n const {error} = await this.props.actions.enableUserAccessToken(tokenId);\n if (error) {\n this.setState({serverError: error.message});\n } else {\n trackEvent('settings', 'activate_user_access_token');\n }\n }\n\n deactivateToken = async (tokenId: string) => {\n const {error} = await this.props.actions.disableUserAccessToken(tokenId);\n if (error) {\n this.setState({serverError: error.message});\n } else {\n trackEvent('settings', 'deactivate_user_access_token');\n }\n }\n\n render() {\n let tokenListClass = '';\n\n if (!this.props.active) {\n const describe = Utils.localizeMessage('user.settings.tokens.clickToEdit', \"Click 'Edit' to manage your personal access tokens\");\n\n return (\n <SettingItemMin\n title={Utils.localizeMessage('user.settings.tokens.title', 'Personal Access Tokens')}\n describe={describe}\n section={SECTION_TOKENS}\n updateSection={this.props.updateSection}\n />\n );\n }\n\n const tokenList: JSX.Element[] = [];\n Object.values(this.props.userAccessTokens).forEach((token) => {\n if (this.state.newToken && this.state.newToken.id === token.id) {\n return;\n }\n\n let activeLink: JSX.Element;\n let activeStatus;\n\n if (token.is_active) {\n activeLink = (\n <a\n id={token.id + '_deactivate'}\n href='#'\n onClick={(e) => {\n e.preventDefault();\n this.deactivateToken(token.id);\n }}\n >\n <FormattedMessage\n id='user.settings.tokens.deactivate'\n defaultMessage='Disable'\n />\n </a>);\n } else {\n activeStatus = (\n <span className='has-error setting-box__inline-error'>\n <FormattedMessage\n id='user.settings.tokens.deactivatedWarning'\n defaultMessage='(Disabled)'\n />\n </span>\n );\n activeLink = (\n <a\n id={token.id + '_activate'}\n href='#'\n onClick={(e) => {\n e.preventDefault();\n this.activateToken(token.id);\n }}\n >\n <FormattedMessage\n id='user.settings.tokens.activate'\n defaultMessage='Enable'\n />\n </a>\n );\n }\n\n tokenList.push(\n <div\n key={token.id}\n className='setting-box__item'\n >\n <div className='whitespace--nowrap overflow--ellipsis'>\n <FormattedMessage\n id='user.settings.tokens.tokenDesc'\n defaultMessage='Token Description: '\n />\n {token.description}\n {activeStatus}\n </div>\n <div className='setting-box__token-id whitespace--nowrap overflow--ellipsis'>\n <FormattedMessage\n id='user.settings.tokens.tokenId'\n defaultMessage='Token ID: '\n />\n {token.id}\n </div>\n <div>\n {activeLink}\n {' - '}\n <a\n id={token.id + '_delete'}\n href='#'\n onClick={(e) => {\n e.preventDefault();\n this.confirmRevokeToken(token.id);\n }}\n >\n <FormattedMessage\n id='user.settings.tokens.delete'\n defaultMessage='Delete'\n />\n </a>\n </div>\n <hr className='mb-3 mt-3'/>\n </div>,\n );\n });\n\n let noTokenText;\n if (tokenList.length === 0) {\n noTokenText = (\n <FormattedMessage\n key='notokens'\n id='user.settings.tokens.userAccessTokensNone'\n defaultMessage='No personal access tokens.'\n />\n );\n }\n\n let extraInfo;\n if (isMobile()) {\n extraInfo = (\n <span>\n <FormattedMarkdownMessage\n id='user.settings.tokens.description_mobile'\n defaultMessage='[Personal access tokens](!https://about.mattermost.com/default-user-access-tokens) function similarly to session tokens and can be used by integrations to [authenticate against the REST API](!https://about.mattermost.com/default-api-authentication). Create new tokens on your desktop.'\n />\n </span>\n );\n } else {\n extraInfo = (\n <span>\n <FormattedMarkdownMessage\n id='user.settings.tokens.description'\n defaultMessage='[Personal access tokens](!https://about.mattermost.com/default-user-access-tokens) function similarly to session tokens and can be used by integrations to [authenticate against the REST API](!https://about.mattermost.com/default-api-authentication).'\n />\n </span>\n );\n }\n\n let newTokenSection;\n if (this.state.tokenCreationState === TOKEN_CREATING) {\n newTokenSection = (\n <div className='pl-3'>\n <div className='row'>\n <label className='col-sm-auto control-label pr-3'>\n <FormattedMessage\n id='user.settings.tokens.name'\n defaultMessage='Token Description: '\n />\n </label>\n <div className='col-sm-5'>\n <input\n autoFocus={true}\n ref={this.newtokendescriptionRef}\n className='form-control'\n type='text'\n maxLength={64}\n onKeyPress={this.saveTokenKeyPress}\n />\n </div>\n </div>\n <div>\n <div className='pt-3'>\n <FormattedMessage\n id='user.settings.tokens.nameHelp'\n defaultMessage='Enter a description for your token to remember what it does.'\n />\n </div>\n <div>\n <label\n id='clientError'\n className='has-error mt-2 mb-2'\n >\n {this.state.tokenError}\n </label>\n </div>\n <SaveButton\n btnClass='btn-primary'\n savingMessage={\n <FormattedMessage\n id='user.settings.tokens.save'\n defaultMessage='Save'\n />\n }\n saving={this.state.saving}\n onClick={this.confirmCreateToken}\n />\n <button\n className='btn btn-link'\n onClick={this.stopCreatingToken}\n >\n <FormattedMessage\n id='user.settings.tokens.cancel'\n defaultMessage='Cancel'\n />\n </button>\n </div>\n </div>\n );\n } else if (this.state.tokenCreationState === TOKEN_CREATED) {\n if (tokenList.length === 0) {\n tokenListClass = ' hidden';\n }\n\n newTokenSection = (\n <div\n className='alert alert-warning'\n >\n <WarningIcon additionalClassName='mr-2'/>\n <FormattedMessage\n id='user.settings.tokens.copy'\n defaultMessage=\"Please copy the access token below. You won't be able to see it again!\"\n />\n <br/>\n <br/>\n <div className='whitespace--nowrap overflow--ellipsis'>\n <FormattedMessage\n id='user.settings.tokens.name'\n defaultMessage='Token Description: '\n />\n {this.state.newToken!.description}\n </div>\n <div className='whitespace--nowrap overflow--ellipsis'>\n <FormattedMessage\n id='user.settings.tokens.id'\n defaultMessage='Token ID: '\n />\n {this.state.newToken!.id}\n </div>\n <strong className='word-break--all'>\n <FormattedMessage\n id='user.settings.tokens.token'\n defaultMessage='Access Token: '\n />\n {this.state.newToken!.token}\n </strong>\n </div>\n );\n } else {\n newTokenSection = (\n <a\n className='btn btn-primary'\n href='#'\n onClick={this.startCreatingToken}\n >\n <FormattedMessage\n id='user.settings.tokens.create'\n defaultMessage='Create Token'\n />\n </a>\n );\n }\n\n const inputs = [];\n inputs.push(\n <div\n key='tokensSetting'\n className='pt-2'\n >\n <div key='tokenList'>\n <div className={'alert alert-transparent' + tokenListClass}>\n {tokenList}\n {noTokenText}\n </div>\n {newTokenSection}\n </div>\n </div>,\n );\n\n return (\n <div>\n <SettingItemMax\n title={Utils.localizeMessage('user.settings.tokens.title', 'Personal Access Tokens')}\n inputs={inputs}\n extraInfo={extraInfo}\n infoPosition='top'\n serverError={this.state.serverError}\n updateSection={this.props.updateSection}\n width='full'\n saving={this.state.saving}\n cancelButtonText={\n <FormattedMessage\n id='user.settings.security.close'\n defaultMessage='Close'\n />\n }\n />\n <ConfirmModal\n title={this.state.confirmTitle}\n message={this.state.confirmMessage ? this.state.confirmMessage(this.state) : null}\n confirmButtonText={this.state.confirmButton}\n show={this.state.showConfirmModal}\n onConfirm={this.state.confirmComplete || (() => null)}\n onCancel={this.handleCancelConfirm}\n hideCancel={this.state.confirmHideCancel}\n />\n </div>\n );\n }\n}\n/* eslint-enable react/no-string-refs */\n","// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.\n// See LICENSE.txt for license information.\n\nimport {connect} from 'react-redux';\nimport {bindActionCreators, Dispatch, ActionCreatorsMapObject} from 'redux';\n\nimport {\n clearUserAccessTokens,\n createUserAccessToken,\n getUserAccessTokensForUser,\n revokeUserAccessToken,\n enableUserAccessToken,\n disableUserAccessToken,\n} from 'mattermost-redux/actions/users';\nimport {GlobalState} from 'mattermost-redux/types/store';\nimport {ActionFunc} from 'mattermost-redux/types/actions';\n\nimport UserAccessTokenSection from './user_access_token_section';\n\ntype Actions = {\n getUserAccessTokensForUser: (userId: string, page: number, perPage: number) => void;\n createUserAccessToken: (userId: string, description: string) => Promise<{\n data: {token: string; description: string; id: string; is_active: boolean} | null;\n error?: {\n message: string;\n };\n }>;\n revokeUserAccessToken: (tokenId: string) => Promise<{\n data: string;\n error?: {\n message: string;\n };\n }>;\n enableUserAccessToken: (tokenId: string) => Promise<{\n data: string;\n error?: {\n message: string;\n };\n }>;\n disableUserAccessToken: (tokenId: string) => Promise<{\n data: string;\n error?: {\n message: string;\n };\n }>;\n clearUserAccessTokens: () => void;\n}\n\nfunction mapStateToProps(state: GlobalState) {\n return {\n userAccessTokens: state.entities.users.myUserAccessTokens,\n };\n}\n\nfunction mapDispatchToProps(dispatch: Dispatch) {\n return {\n actions: bindActionCreators<ActionCreatorsMapObject<ActionFunc>, Actions>({\n getUserAccessTokensForUser,\n createUserAccessToken,\n revokeUserAccessToken,\n enableUserAccessToken,\n disableUserAccessToken,\n clearUserAccessTokens,\n }, dispatch),\n };\n}\n\nexport default connect(mapStateToProps, mapDispatchToProps)(UserAccessTokenSection);\n","// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.\n// See LICENSE.txt for license information.\n/* eslint-disable react/no-string-refs */\n\nimport React from 'react';\nimport {FormattedDate, FormattedMessage, FormattedTime} from 'react-intl';\nimport {Link} from 'react-router-dom';\n\nimport {UserProfile} from 'mattermost-redux/types/users';\nimport {ActionResult} from 'mattermost-redux/types/actions';\nimport {OAuthApp} from 'mattermost-redux/types/integrations';\n\nimport Constants from 'utils/constants';\nimport * as Utils from 'utils/utils.jsx';\nimport icon50 from 'images/icon50x50.png';\nimport AccessHistoryModal from 'components/access_history_modal';\nimport ActivityLogModal from 'components/activity_log_modal';\nimport SettingItemMax from 'components/setting_item_max.jsx';\nimport SettingItemMin from 'components/setting_item_min';\nimport ToggleModalButton from 'components/toggle_modal_button.jsx';\n\nimport MfaSection from './mfa_section';\nimport UserAccessTokenSection from './user_access_token_section';\n\nconst SECTION_MFA = 'mfa';\nconst SECTION_PASSWORD = 'password';\nconst SECTION_SIGNIN = 'signin';\nconst SECTION_APPS = 'apps';\nconst SECTION_TOKENS = 'tokens';\n\ntype Actions = {\n getMe: () => void;\n updateUserPassword: (\n userId: string,\n currentPassword: string,\n newPassword: string\n ) => Promise<ActionResult>;\n getAuthorizedOAuthApps: () => Promise<ActionResult>;\n deauthorizeOAuthApp: (clientId: string) => Promise<ActionResult>;\n};\n\ntype Props = {\n user: UserProfile;\n activeSection?: string;\n updateSection: (section: string) => void;\n closeModal: () => void;\n collapseModal: () => void;\n setRequireConfirm: () => void;\n canUseAccessTokens: boolean;\n enableOAuthServiceProvider: boolean;\n enableSignUpWithEmail: boolean;\n enableSignUpWithGitLab: boolean;\n enableSignUpWithGoogle: boolean;\n enableSignUpWithOpenId: boolean;\n enableLdap: boolean;\n enableSaml: boolean;\n enableSignUpWithOffice365: boolean;\n experimentalEnableAuthenticationTransfer: boolean;\n passwordConfig: Record<string, unknown>;\n militaryTime: boolean;\n actions: Actions;\n};\n\ntype State = {\n currentPassword: string;\n newPassword: string;\n confirmPassword: string;\n passwordError: React.ReactNode;\n serverError: string | null;\n tokenError: string;\n savingPassword: boolean;\n authorizedApps: OAuthApp[];\n};\n\nexport default class SecurityTab extends React.PureComponent<Props, State> {\n constructor(props: Props) {\n super(props);\n this.state = this.getDefaultState();\n }\n\n getDefaultState() {\n return {\n currentPassword: '',\n newPassword: '',\n confirmPassword: '',\n passwordError: '',\n serverError: '',\n tokenError: '',\n authService: this.props.user.auth_service,\n savingPassword: false,\n authorizedApps: [],\n };\n }\n\n componentDidMount() {\n if (this.props.enableOAuthServiceProvider) {\n this.loadAuthorizedOAuthApps();\n }\n }\n\n loadAuthorizedOAuthApps = async () => {\n const res = await this.props.actions.getAuthorizedOAuthApps();\n if ('data' in res) {\n const {data} = res;\n this.setState({authorizedApps: data, serverError: null}); //eslint-disable-line react/no-did-mount-set-state\n } else if ('error' in res) {\n const {error} = res;\n this.setState({serverError: error.message}); //eslint-disable-line react/no-did-mount-set-state\n }\n };\n\n submitPassword = async () => {\n const user = this.props.user;\n const currentPassword = this.state.currentPassword;\n const newPassword = this.state.newPassword;\n const confirmPassword = this.state.confirmPassword;\n\n if (currentPassword === '') {\n this.setState({\n passwordError: Utils.localizeMessage(\n 'user.settings.security.currentPasswordError',\n 'Please enter your current password.',\n ),\n serverError: '',\n });\n return;\n }\n\n const {valid, error} = Utils.isValidPassword(\n newPassword,\n this.props.passwordConfig,\n );\n if (!valid && error) {\n this.setState({\n passwordError: error,\n serverError: '',\n });\n return;\n }\n\n if (newPassword !== confirmPassword) {\n const defaultState = Object.assign(this.getDefaultState(), {\n passwordError: Utils.localizeMessage(\n 'user.settings.security.passwordMatchError',\n 'The new passwords you entered do not match.',\n ),\n serverError: '',\n });\n this.setState(defaultState);\n return;\n }\n\n this.setState({savingPassword: true});\n\n const res = await this.props.actions.updateUserPassword(\n user.id,\n currentPassword,\n newPassword,\n );\n if ('data' in res) {\n this.props.updateSection('');\n this.props.actions.getMe();\n this.setState(this.getDefaultState());\n } else if ('error' in res) {\n const {error: err} = res;\n const state = this.getDefaultState();\n if (err.message) {\n state.serverError = err.message;\n } else {\n state.serverError = err;\n }\n state.passwordError = '';\n this.setState(state);\n }\n };\n\n updateCurrentPassword = (e: React.ChangeEvent<HTMLInputElement>) => {\n this.setState({currentPassword: e.target.value});\n };\n\n updateNewPassword = (e: React.ChangeEvent<HTMLInputElement>) => {\n this.setState({newPassword: e.target.value});\n };\n\n updateConfirmPassword = (e: React.ChangeEvent<HTMLInputElement>) => {\n this.setState({confirmPassword: e.target.value});\n };\n\n deauthorizeApp = async (e: React.MouseEvent) => {\n e.preventDefault();\n\n const appId = e.currentTarget.getAttribute('data-app') as string;\n\n const res = await this.props.actions.deauthorizeOAuthApp(appId);\n if ('data' in res) {\n const authorizedApps = this.state.authorizedApps.filter((app) => {\n return app.id !== appId;\n });\n this.setState({authorizedApps, serverError: null});\n } else if ('error' in res) {\n const {error} = res;\n this.setState({serverError: error.message});\n }\n };\n\n handleUpdateSection = (section: string) => {\n if (section) {\n this.props.updateSection(section);\n } else {\n switch (this.props.activeSection) {\n case SECTION_MFA:\n case SECTION_SIGNIN:\n case SECTION_TOKENS:\n case SECTION_APPS:\n this.setState({\n serverError: null,\n });\n break;\n case SECTION_PASSWORD:\n this.setState({\n currentPassword: '',\n newPassword: '',\n confirmPassword: '',\n serverError: null,\n passwordError: null,\n });\n break;\n default:\n }\n\n this.props.updateSection('');\n }\n };\n\n createPasswordSection = () => {\n if (this.props.activeSection === SECTION_PASSWORD) {\n const inputs = [];\n let submit;\n\n if (this.props.user.auth_service === '') {\n submit = this.submitPassword;\n\n inputs.push(\n <div\n key='currentPasswordUpdateForm'\n className='form-group'\n >\n <label className='col-sm-5 control-label'>\n <FormattedMessage\n id='user.settings.security.currentPassword'\n defaultMessage='Current Password'\n />\n </label>\n <div className='col-sm-7'>\n <input\n id='currentPassword'\n autoFocus={true}\n className='form-control'\n type='password'\n onChange={this.updateCurrentPassword}\n value={this.state.currentPassword}\n aria-label={Utils.localizeMessage(\n 'user.settings.security.currentPassword',\n 'Current Password',\n )}\n />\n </div>\n </div>,\n );\n inputs.push(\n <div\n key='newPasswordUpdateForm'\n className='form-group'\n >\n <label className='col-sm-5 control-label'>\n <FormattedMessage\n id='user.settings.security.newPassword'\n defaultMessage='New Password'\n />\n </label>\n <div className='col-sm-7'>\n <input\n id='newPassword'\n className='form-control'\n type='password'\n onChange={this.updateNewPassword}\n value={this.state.newPassword}\n aria-label={Utils.localizeMessage(\n 'user.settings.security.newPassword',\n 'New Password',\n )}\n />\n </div>\n </div>,\n );\n inputs.push(\n <div\n key='retypeNewPasswordUpdateForm'\n className='form-group'\n >\n <label className='col-sm-5 control-label'>\n <FormattedMessage\n id='user.settings.security.retypePassword'\n defaultMessage='Retype New Password'\n />\n </label>\n <div className='col-sm-7'>\n <input\n id='confirmPassword'\n className='form-control'\n type='password'\n onChange={this.updateConfirmPassword}\n value={this.state.confirmPassword}\n aria-label={Utils.localizeMessage(\n 'user.settings.security.retypePassword',\n 'Retype New Password',\n )}\n />\n </div>\n </div>,\n );\n } else if (\n this.props.user.auth_service === Constants.GITLAB_SERVICE\n ) {\n inputs.push(\n <div\n key='oauthEmailInfo'\n className='form-group'\n >\n <div className='pb-3'>\n <FormattedMessage\n id='user.settings.security.passwordGitlabCantUpdate'\n defaultMessage='Login occurs through GitLab. Password cannot be updated.'\n />\n </div>\n </div>,\n );\n } else if (\n this.props.user.auth_service === Constants.LDAP_SERVICE\n ) {\n inputs.push(\n <div\n key='oauthEmailInfo'\n className='form-group'\n >\n <div className='pb-3'>\n <FormattedMessage\n id='user.settings.security.passwordLdapCantUpdate'\n defaultMessage='Login occurs through AD/LDAP. Password cannot be updated.'\n />\n </div>\n </div>,\n );\n } else if (\n this.props.user.auth_service === Constants.SAML_SERVICE\n ) {\n inputs.push(\n <div\n key='oauthEmailInfo'\n className='form-group'\n >\n <div className='pb-3'>\n <FormattedMessage\n id='user.settings.security.passwordSamlCantUpdate'\n defaultMessage='This field is handled through your login provider. If you want to change it, you need to do so through your login provider.'\n />\n </div>\n </div>,\n );\n } else if (\n this.props.user.auth_service === Constants.GOOGLE_SERVICE\n ) {\n inputs.push(\n <div\n key='oauthEmailInfo'\n className='form-group'\n >\n <div className='pb-3'>\n <FormattedMessage\n id='user.settings.security.passwordGoogleCantUpdate'\n defaultMessage='Login occurs through Google Apps. Password cannot be updated.'\n />\n </div>\n </div>,\n );\n } else if (\n this.props.user.auth_service === Constants.OFFICE365_SERVICE\n ) {\n inputs.push(\n <div\n key='oauthEmailInfo'\n className='form-group'\n >\n <div className='pb-3'>\n <FormattedMessage\n id='user.settings.security.passwordOffice365CantUpdate'\n defaultMessage='Login occurs through Office 365. Password cannot be updated.'\n />\n </div>\n </div>,\n );\n }\n\n return (\n <SettingItemMax\n title={\n <FormattedMessage\n id='user.settings.security.password'\n defaultMessage='Password'\n />\n }\n inputs={inputs}\n submit={submit}\n saving={this.state.savingPassword}\n serverError={this.state.serverError}\n clientError={this.state.passwordError}\n updateSection={this.handleUpdateSection}\n />\n );\n }\n\n let describe;\n\n if (this.props.user.auth_service === '') {\n const d = new Date(this.props.user.last_password_update);\n\n describe = (\n <FormattedMessage\n id='user.settings.security.lastUpdated'\n defaultMessage='Last updated {date} at {time}'\n values={{\n date: (\n <FormattedDate\n value={d}\n day='2-digit'\n month='short'\n year='numeric'\n />\n ),\n time: (\n <FormattedTime\n value={d}\n hour12={!this.props.militaryTime}\n hour='2-digit'\n minute='2-digit'\n />\n ),\n }}\n />\n );\n } else if (this.props.user.auth_service === Constants.GITLAB_SERVICE) {\n describe = (\n <FormattedMessage\n id='user.settings.security.loginGitlab'\n defaultMessage='Login done through GitLab'\n />\n );\n } else if (this.props.user.auth_service === Constants.LDAP_SERVICE) {\n describe = (\n <FormattedMessage\n id='user.settings.security.loginLdap'\n defaultMessage='Login done through AD/LDAP'\n />\n );\n } else if (this.props.user.auth_service === Constants.SAML_SERVICE) {\n describe = (\n <FormattedMessage\n id='user.settings.security.loginSaml'\n defaultMessage='Login done through SAML'\n />\n );\n } else if (this.props.user.auth_service === Constants.GOOGLE_SERVICE) {\n describe = (\n <FormattedMessage\n id='user.settings.security.loginGoogle'\n defaultMessage='Login done through Google Apps'\n />\n );\n } else if (\n this.props.user.auth_service === Constants.OFFICE365_SERVICE\n ) {\n describe = (\n <FormattedMessage\n id='user.settings.security.loginOffice365'\n defaultMessage='Login done through Office 365'\n />\n );\n }\n\n return (\n <SettingItemMin\n title={\n <FormattedMessage\n id='user.settings.security.password'\n defaultMessage='Password'\n />\n }\n describe={describe}\n section={SECTION_PASSWORD}\n updateSection={this.handleUpdateSection}\n />\n );\n };\n\n createSignInSection = () => {\n const user = this.props.user;\n\n if (this.props.activeSection === SECTION_SIGNIN) {\n let emailOption;\n let gitlabOption;\n let googleOption;\n let office365Option;\n let openidOption;\n let ldapOption;\n let samlOption;\n\n if (user.auth_service === '') {\n if (this.props.enableSignUpWithGitLab) {\n gitlabOption = (\n <div className='pb-3'>\n <Link\n className='btn btn-primary'\n to={\n '/claim/email_to_oauth?email=' +\n encodeURIComponent(user.email) +\n '&old_type=' +\n user.auth_service +\n '&new_type=' +\n Constants.GITLAB_SERVICE\n }\n >\n <FormattedMessage\n id='user.settings.security.switchGitlab'\n defaultMessage='Switch to Using GitLab SSO'\n />\n </Link>\n <br/>\n </div>\n );\n }\n\n if (this.props.enableSignUpWithGoogle) {\n googleOption = (\n <div className='pb-3'>\n <Link\n className='btn btn-primary'\n to={\n '/claim/email_to_oauth?email=' +\n encodeURIComponent(user.email) +\n '&old_type=' +\n user.auth_service +\n '&new_type=' +\n Constants.GOOGLE_SERVICE\n }\n >\n <FormattedMessage\n id='user.settings.security.switchGoogle'\n defaultMessage='Switch to Using Google SSO'\n />\n </Link>\n <br/>\n </div>\n );\n }\n\n if (this.props.enableSignUpWithOffice365) {\n office365Option = (\n <div className='pb-3'>\n <Link\n className='btn btn-primary'\n to={\n '/claim/email_to_oauth?email=' +\n encodeURIComponent(user.email) +\n '&old_type=' +\n user.auth_service +\n '&new_type=' +\n Constants.OFFICE365_SERVICE\n }\n >\n <FormattedMessage\n id='user.settings.security.switchOffice365'\n defaultMessage='Switch to Using Office 365 SSO'\n />\n </Link>\n <br/>\n </div>\n );\n }\n\n if (this.props.enableSignUpWithOpenId) {\n openidOption = (\n <div className='pb-3'>\n <Link\n className='btn btn-primary'\n to={\n '/claim/email_to_oauth?email=' +\n encodeURIComponent(user.email) +\n '&old_type=' +\n user.auth_service +\n '&new_type=' +\n Constants.OPENID_SERVICE\n }\n >\n <FormattedMessage\n id='user.settings.security.switchOpenId'\n defaultMessage='Switch to Using OpenID SSO'\n />\n </Link>\n <br/>\n </div>\n );\n }\n\n if (this.props.enableLdap) {\n ldapOption = (\n <div className='pb-3'>\n <Link\n className='btn btn-primary'\n to={\n '/claim/email_to_ldap?email=' +\n encodeURIComponent(user.email)\n }\n >\n <FormattedMessage\n id='user.settings.security.switchLdap'\n defaultMessage='Switch to Using AD/LDAP'\n />\n </Link>\n <br/>\n </div>\n );\n }\n\n if (this.props.enableSaml) {\n samlOption = (\n <div className='pb-3'>\n <Link\n className='btn btn-primary'\n to={\n '/claim/email_to_oauth?email=' +\n encodeURIComponent(user.email) +\n '&old_type=' +\n user.auth_service +\n '&new_type=' +\n Constants.SAML_SERVICE\n }\n >\n <FormattedMessage\n id='user.settings.security.switchSaml'\n defaultMessage='Switch to Using SAML SSO'\n />\n </Link>\n <br/>\n </div>\n );\n }\n } else if (this.props.enableSignUpWithEmail) {\n let link;\n if (user.auth_service === Constants.LDAP_SERVICE) {\n link =\n '/claim/ldap_to_email?email=' +\n encodeURIComponent(user.email);\n } else {\n link =\n '/claim/oauth_to_email?email=' +\n encodeURIComponent(user.email) +\n '&old_type=' +\n user.auth_service;\n }\n\n emailOption = (\n <div className='pb-3'>\n <Link\n className='btn btn-primary'\n to={link}\n >\n <FormattedMessage\n id='user.settings.security.switchEmail'\n defaultMessage='Switch to Using Email and Password'\n />\n </Link>\n <br/>\n </div>\n );\n }\n\n const inputs = [];\n inputs.push(\n <div key='userSignInOption'>\n {emailOption}\n {gitlabOption}\n {googleOption}\n {office365Option}\n {openidOption}\n {ldapOption}\n {samlOption}\n </div>,\n );\n\n const extraInfo = (\n <span>\n <FormattedMessage\n id='user.settings.security.oneSignin'\n defaultMessage='You may only have one sign-in method at a time. Switching sign-in method will send an email notifying you if the change was successful.'\n />\n </span>\n );\n\n return (\n <SettingItemMax\n title={Utils.localizeMessage(\n 'user.settings.security.method',\n 'Sign-in Method',\n )}\n extraInfo={extraInfo}\n inputs={inputs}\n serverError={this.state.serverError}\n updateSection={this.handleUpdateSection}\n />\n );\n }\n\n let describe = (\n <FormattedMessage\n id='user.settings.security.emailPwd'\n defaultMessage='Email and Password'\n />\n );\n if (this.props.user.auth_service === Constants.GITLAB_SERVICE) {\n describe = (\n <FormattedMessage\n id='user.settings.security.gitlab'\n defaultMessage='GitLab'\n />\n );\n } else if (this.props.user.auth_service === Constants.GOOGLE_SERVICE) {\n describe = (\n <FormattedMessage\n id='user.settings.security.google'\n defaultMessage='Google'\n />\n );\n } else if (\n this.props.user.auth_service === Constants.OFFICE365_SERVICE\n ) {\n describe = (\n <FormattedMessage\n id='user.settings.security.office365'\n defaultMessage='Office 365'\n />\n );\n } else if (\n this.props.user.auth_service === Constants.OPENID_SERVICE\n ) {\n describe = (\n <FormattedMessage\n id='user.settings.security.openid'\n defaultMessage='OpenID'\n />\n );\n } else if (this.props.user.auth_service === Constants.LDAP_SERVICE) {\n describe = (\n <FormattedMessage\n id='user.settings.security.ldap'\n defaultMessage='AD/LDAP'\n />\n );\n } else if (this.props.user.auth_service === Constants.SAML_SERVICE) {\n describe = (\n <FormattedMessage\n id='user.settings.security.saml'\n defaultMessage='SAML'\n />\n );\n }\n\n return (\n <SettingItemMin\n title={Utils.localizeMessage(\n 'user.settings.security.method',\n 'Sign-in Method',\n )}\n describe={describe}\n section={SECTION_SIGNIN}\n updateSection={this.handleUpdateSection}\n />\n );\n };\n\n createOAuthAppsSection = () => {\n if (this.props.activeSection === SECTION_APPS) {\n let apps;\n if (\n this.state.authorizedApps &&\n this.state.authorizedApps.length > 0\n ) {\n apps = this.state.authorizedApps.map((app) => {\n const homepage = (\n <a\n href={app.homepage}\n target='_blank'\n rel='noopener noreferrer'\n >\n {app.homepage}\n </a>\n );\n\n return (\n <div\n key={app.id}\n className='pb-3 authorized-app'\n >\n <div className='col-sm-10'>\n <div className='authorized-app__name'>\n {app.name}\n <span className='authorized-app__url'>\n {' -'} {homepage}\n </span>\n </div>\n <div className='authorized-app__description'>\n {app.description}\n </div>\n <div className='authorized-app__deauthorize'>\n <a\n href='#'\n data-app={app.id}\n onClick={this.deauthorizeApp}\n >\n <FormattedMessage\n id='user.settings.security.deauthorize'\n defaultMessage='Deauthorize'\n />\n </a>\n </div>\n </div>\n <div className='col-sm-2 pull-right'>\n <img\n alt={app.name}\n src={app.icon_url || icon50}\n />\n </div>\n <br/>\n </div>\n );\n });\n } else {\n apps = (\n <div className='pb-3 authorized-app'>\n <div className='setting-list__hint'>\n <FormattedMessage\n id='user.settings.security.noApps'\n defaultMessage='No OAuth 2.0 Applications are authorized.'\n />\n </div>\n </div>\n );\n }\n\n const inputs = [];\n let wrapperClass;\n let helpText;\n if (Array.isArray(apps)) {\n wrapperClass = 'authorized-apps__wrapper';\n\n helpText = (\n <div className='authorized-apps__help'>\n <FormattedMessage\n id='user.settings.security.oauthAppsHelp'\n defaultMessage='Applications act on your behalf to access your data based on the permissions you grant them.'\n />\n </div>\n );\n }\n\n inputs.push(\n <div\n className={wrapperClass}\n key='authorizedApps'\n >\n {apps}\n </div>,\n );\n\n const title = (\n <div>\n <FormattedMessage\n id='user.settings.security.oauthApps'\n defaultMessage='OAuth 2.0 Applications'\n />\n {helpText}\n </div>\n );\n\n return (\n <SettingItemMax\n title={title}\n inputs={inputs}\n serverError={this.state.serverError}\n updateSection={this.handleUpdateSection}\n width='full'\n cancelButtonText={\n <FormattedMessage\n id='user.settings.security.close'\n defaultMessage='Close'\n />\n }\n />\n );\n }\n\n return (\n <SettingItemMin\n title={Utils.localizeMessage(\n 'user.settings.security.oauthApps',\n 'OAuth 2.0 Applications',\n )}\n describe={\n <FormattedMessage\n id='user.settings.security.oauthAppsDescription'\n defaultMessage=\"Click 'Edit' to manage your OAuth 2.0 Applications\"\n />\n }\n section={SECTION_APPS}\n updateSection={this.handleUpdateSection}\n />\n );\n };\n\n render() {\n const user = this.props.user;\n\n const passwordSection = this.createPasswordSection();\n\n let numMethods = 0;\n numMethods = this.props.enableSignUpWithGitLab ? numMethods + 1 : numMethods;\n numMethods = this.props.enableSignUpWithGoogle ? numMethods + 1 : numMethods;\n numMethods = this.props.enableSignUpWithOffice365 ? numMethods + 1 : numMethods;\n numMethods = this.props.enableSignUpWithOpenId ? numMethods + 1 : numMethods;\n numMethods = this.props.enableLdap ? numMethods + 1 : numMethods;\n numMethods = this.props.enableSaml ? numMethods + 1 : numMethods;\n\n // If there are other sign-in methods and either email is enabled or the user's account is email, then allow switching\n let signInSection;\n if (\n (this.props.enableSignUpWithEmail || user.auth_service === '') &&\n numMethods > 0 &&\n this.props.experimentalEnableAuthenticationTransfer\n ) {\n signInSection = this.createSignInSection();\n }\n\n let oauthSection;\n if (this.props.enableOAuthServiceProvider) {\n oauthSection = this.createOAuthAppsSection();\n }\n\n let tokensSection;\n if (this.props.canUseAccessTokens) {\n tokensSection = (\n <UserAccessTokenSection\n user={this.props.user}\n active={this.props.activeSection === SECTION_TOKENS}\n updateSection={this.handleUpdateSection}\n setRequireConfirm={this.props.setRequireConfirm}\n />\n );\n }\n\n return (\n <div>\n <div className='modal-header'>\n <FormattedMessage\n id='user.settings.security.close'\n defaultMessage='Close'\n >\n {(ariaLabel: string) => (\n <button\n type='button'\n className='close'\n data-dismiss='modal'\n aria-label={ariaLabel}\n onClick={this.props.closeModal}\n >\n <span aria-hidden='true'>{'×'}</span>\n </button>\n )}\n </FormattedMessage>\n <h4\n className='modal-title'\n ref='title'\n >\n <div className='modal-back'>\n <FormattedMessage\n id='generic_icons.collapse'\n defaultMessage='Collapse Icon'\n >\n {(title: string) => (\n <i\n className='fa fa-angle-left'\n title={title}\n onClick={this.props.collapseModal}\n />\n )}\n </FormattedMessage>\n </div>\n <FormattedMessage\n id='user.settings.security.title'\n defaultMessage='Security Settings'\n />\n </h4>\n </div>\n <div className='user-settings'>\n <h3 className='tab-header'>\n <FormattedMessage\n id='user.settings.security.title'\n defaultMessage='Security Settings'\n />\n </h3>\n <div className='divider-dark first'/>\n {passwordSection}\n <div className='divider-light'/>\n <MfaSection\n active={this.props.activeSection === SECTION_MFA}\n updateSection={this.handleUpdateSection}\n />\n <div className='divider-light'/>\n {oauthSection}\n <div className='divider-light'/>\n {tokensSection}\n <div className='divider-light'/>\n {signInSection}\n <div className='divider-dark'/>\n <br/>\n <ToggleModalButton\n className='security-links color--link'\n dialogType={AccessHistoryModal}\n id='viewAccessHistory'\n >\n <FormattedMessage\n id='user.settings.security.viewHistory.icon'\n defaultMessage='Access History Icon'\n >\n {(title: string) => (\n <i\n className='fa fa-clock-o'\n title={title}\n />\n )}\n </FormattedMessage>\n <FormattedMessage\n id='user.settings.security.viewHistory'\n defaultMessage='View Access History'\n />\n </ToggleModalButton>\n <ToggleModalButton\n className='security-links color--link mt-2'\n dialogType={ActivityLogModal}\n id='viewAndLogOutOfActiveSessions'\n >\n <FormattedMessage\n id='user.settings.security.logoutActiveSessions.icon'\n defaultMessage='Active Sessions Icon'\n >\n {(title: string) => (\n <i\n className='fa fa-clock-o'\n title={title}\n />\n )}\n </FormattedMessage>\n <FormattedMessage\n id='user.settings.security.logoutActiveSessions'\n defaultMessage='View and Log Out of Active Sessions'\n />\n </ToggleModalButton>\n </div>\n </div>\n );\n }\n}\n/* eslint-enable react/no-string-refs */\n","// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.\n// See LICENSE.txt for license information.\n\nimport {connect} from 'react-redux';\nimport {ActionCreatorsMapObject, bindActionCreators, Dispatch} from 'redux';\n\nimport {getMe, updateUserPassword} from 'mattermost-redux/actions/users';\nimport {getAuthorizedOAuthApps, deauthorizeOAuthApp} from 'mattermost-redux/actions/integrations';\nimport * as UserUtils from 'mattermost-redux/utils/user_utils';\nimport {getConfig} from 'mattermost-redux/selectors/entities/general';\nimport {getBool} from 'mattermost-redux/selectors/entities/preferences';\nimport {GlobalState} from 'mattermost-redux/types/store';\nimport {UserProfile} from 'mattermost-redux/types/users';\nimport {ActionFunc, ActionResult} from 'mattermost-redux/types/actions';\n\nimport {getPasswordConfig} from 'utils/utils.jsx';\nimport {Preferences} from 'utils/constants';\n\nimport SecurityTab from './user_settings_security';\n\ntype Actions = {\n getMe: () => void;\n updateUserPassword: (userId: string, currentPassword: string, newPassword: string) => Promise<ActionResult>;\n getAuthorizedOAuthApps: () => Promise<ActionResult>;\n deauthorizeOAuthApp: (clientId: string) => Promise<ActionResult>;\n};\n\ntype Props = {\n user: UserProfile;\n activeSection?: string;\n updateSection: (section: string) => void;\n closeModal: () => void;\n collapseModal: () => void;\n setRequireConfirm: () => void;\n};\n\nfunction mapStateToProps(state: GlobalState, ownProps: Props) {\n const config = getConfig(state);\n\n const tokensEnabled = config.EnableUserAccessTokens === 'true';\n const userHasTokenRole = UserUtils.hasUserAccessTokenRole(ownProps.user.roles) || UserUtils.isSystemAdmin(ownProps.user.roles);\n\n const enableOAuthServiceProvider = config.EnableOAuthServiceProvider === 'true';\n const enableSignUpWithEmail = config.EnableSignUpWithEmail === 'true';\n const enableSignUpWithGitLab = config.EnableSignUpWithGitLab === 'true';\n const enableSignUpWithGoogle = config.EnableSignUpWithGoogle === 'true';\n const enableSignUpWithOpenId = config.EnableSignUpWithOpenId === 'true';\n const enableLdap = config.EnableLdap === 'true';\n const enableSaml = config.EnableSaml === 'true';\n const enableSignUpWithOffice365 = config.EnableSignUpWithOffice365 === 'true';\n const experimentalEnableAuthenticationTransfer = config.ExperimentalEnableAuthenticationTransfer === 'true';\n\n return {\n canUseAccessTokens: tokensEnabled && userHasTokenRole,\n enableOAuthServiceProvider,\n enableSignUpWithEmail,\n enableSignUpWithGitLab,\n enableSignUpWithGoogle,\n enableSignUpWithOpenId,\n enableLdap,\n enableSaml,\n enableSignUpWithOffice365,\n experimentalEnableAuthenticationTransfer,\n passwordConfig: getPasswordConfig(config),\n militaryTime: getBool(state, Preferences.CATEGORY_DISPLAY_SETTINGS, Preferences.USE_MILITARY_TIME, false),\n };\n}\n\nfunction mapDispatchToProps(dispatch: Dispatch) {\n return {\n actions: bindActionCreators<ActionCreatorsMapObject<ActionFunc>, Actions>({\n getMe,\n updateUserPassword,\n getAuthorizedOAuthApps,\n deauthorizeOAuthApp,\n }, dispatch),\n };\n}\n\nexport default connect(mapStateToProps, mapDispatchToProps)(SecurityTab);\n","// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.\n// See LICENSE.txt for license information.\n\nimport React from 'react';\nimport {FormattedMessage} from 'react-intl';\n\nimport {Preferences} from 'mattermost-redux/constants';\nimport {PreferenceType} from 'mattermost-redux/types/preferences';\n\nimport SettingItemMax from 'components/setting_item_max';\nimport SettingItemMin from 'components/setting_item_min';\n\ntype Props = {\n active: boolean;\n currentUserId: string;\n savePreferences: (userId: string, preferences: PreferenceType[]) => Promise<{data: boolean}>;\n showUnreadsCategory: boolean;\n updateSection: (section: string) => void;\n}\n\ntype State = {\n active: boolean;\n checked: boolean;\n isSaving: boolean;\n}\n\nexport default class ShowUnreadsCategory extends React.PureComponent<Props, State> {\n constructor(props: Props) {\n super(props);\n\n this.state = {\n active: false,\n checked: false,\n isSaving: false,\n };\n }\n\n static getDerivedStateFromProps(props: Props, state: State) {\n if (props.active !== state.active) {\n if (props.active && !state.active) {\n return {\n checked: props.showUnreadsCategory,\n active: props.active,\n };\n }\n\n return {\n active: props.active,\n };\n }\n\n return null;\n }\n\n handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n this.setState({\n checked: e.target.value === 'true',\n });\n }\n\n handleSubmit = async () => {\n this.setState({isSaving: true});\n\n await this.props.savePreferences(this.props.currentUserId, [{\n user_id: this.props.currentUserId,\n category: Preferences.CATEGORY_SIDEBAR_SETTINGS,\n name: Preferences.SHOW_UNREAD_SECTION,\n value: this.state.checked.toString(),\n }]);\n\n this.setState({isSaving: false});\n\n this.props.updateSection('');\n }\n\n renderDescription = () => {\n if (this.props.showUnreadsCategory) {\n return (\n <FormattedMessage\n id='user.settings.sidebar.on'\n defaultMessage='On'\n />\n );\n }\n\n return (\n <FormattedMessage\n id='user.settings.sidebar.off'\n defaultMessage='Off'\n />\n );\n }\n\n render() {\n const title = (\n <FormattedMessage\n id='user.settings.sidebar.showUnreadsCategoryTitle'\n defaultMessage='Group unread channels separately'\n />\n );\n\n if (!this.props.active) {\n return (\n <SettingItemMin\n title={title}\n describe={this.renderDescription()}\n section='showUnreadsCategory'\n updateSection={this.props.updateSection}\n />\n );\n }\n\n return (\n <SettingItemMax\n title={title}\n inputs={\n <fieldset>\n <legend className='form-legend hidden-label'>\n {title}\n </legend>\n <div className='radio'>\n <label>\n <input\n data-testid='showUnreadsCategoryOn'\n type='radio'\n name='showUnreadsCategory'\n checked={this.state.checked}\n onChange={() => this.setState({checked: true})}\n />\n <FormattedMessage\n id='user.settings.sidebar.on'\n defaultMessage='On'\n />\n </label>\n <br/>\n </div>\n <div className='radio'>\n <label>\n <input\n data-testid='showUnreadsCategoryOff'\n type='radio'\n name='showUnreadsCategory'\n checked={!this.state.checked}\n onChange={() => this.setState({checked: false})}\n />\n <FormattedMessage\n id='user.settings.sidebar.off'\n defaultMessage='Off'\n />\n </label>\n <br/>\n </div>\n <div className='mt-5'>\n <FormattedMessage\n id='user.settings.sidebar.showUnreadsCategoryDesc'\n defaultMessage='When enabled, all unread channels and direct messages will be grouped together in the sidebar.'\n />\n </div>\n </fieldset>\n }\n submit={this.handleSubmit}\n saving={this.state.isSaving}\n updateSection={this.props.updateSection}\n />\n );\n }\n}\n","// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.\n// See LICENSE.txt for license information.\n\nimport {connect} from 'react-redux';\n\nimport {savePreferences} from 'mattermost-redux/actions/preferences';\nimport {shouldShowUnreadsCategory} from 'mattermost-redux/selectors/entities/preferences';\nimport {getCurrentUserId} from 'mattermost-redux/selectors/entities/users';\n\nimport {GlobalState} from 'types/store';\n\nimport ShowUnreadsCategory from './show_unreads_category';\n\nfunction mapStateToProps(state: GlobalState) {\n return {\n currentUserId: getCurrentUserId(state),\n showUnreadsCategory: shouldShowUnreadsCategory(state),\n };\n}\n\nconst mapDispatchToProps = {\n savePreferences,\n};\n\nexport default connect(mapStateToProps, mapDispatchToProps)(ShowUnreadsCategory);\n","// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.\n// See LICENSE.txt for license information.\n\nimport React from 'react';\nimport ReactSelect, {ValueType} from 'react-select';\nimport {FormattedMessage} from 'react-intl';\n\nimport {Preferences} from 'mattermost-redux/constants';\nimport {PreferenceType} from 'mattermost-redux/types/preferences';\n\nimport SettingItemMax from 'components/setting_item_max';\nimport SettingItemMin from 'components/setting_item_min';\nimport {localizeMessage} from 'utils/utils';\n\ntype Limit = {\n value: number;\n label: string;\n};\n\ntype Props = {\n active: boolean;\n currentUserId: string;\n savePreferences: (userId: string, preferences: PreferenceType[]) => Promise<{data: boolean}>;\n dmGmLimit: number;\n updateSection: (section: string) => void;\n}\n\ntype State = {\n active: boolean;\n limit: Limit;\n isSaving: boolean;\n}\n\nconst limits: Limit[] = [\n {value: 10000, label: localizeMessage('user.settings.sidebar.limitVisibleGMsDMs.allDirectMessages', 'All Direct Messages')},\n {value: 10, label: '10'},\n {value: 15, label: '15'},\n {value: 20, label: '20'},\n {value: 40, label: '40'},\n];\n\nexport default class LimitVisibleGMsDMs extends React.PureComponent<Props, State> {\n constructor(props: Props) {\n super(props);\n\n this.state = {\n active: false,\n limit: {value: 20, label: '20'},\n isSaving: false,\n };\n }\n\n static getDerivedStateFromProps(props: Props, state: State) {\n if (props.active !== state.active) {\n if (props.active && !state.active) {\n return {\n limit: limits.find((l) => l.value === props.dmGmLimit),\n active: props.active,\n };\n }\n\n return {\n active: props.active,\n };\n } else if (!props.active) {\n return {\n limit: limits.find((l) => l.value === props.dmGmLimit),\n };\n }\n\n return null;\n }\n\n handleChange = (selected: ValueType<Limit>) => {\n if (selected && 'value' in selected) {\n this.setState({limit: selected});\n }\n }\n\n handleSubmit = async () => {\n this.setState({isSaving: true});\n\n await this.props.savePreferences(this.props.currentUserId, [{\n user_id: this.props.currentUserId,\n category: Preferences.CATEGORY_SIDEBAR_SETTINGS,\n name: Preferences.LIMIT_VISIBLE_DMS_GMS,\n value: this.state.limit.value.toString(),\n }]);\n\n this.setState({isSaving: false});\n\n this.props.updateSection('');\n }\n\n renderDescription = () => {\n return (\n <span>{this.state.limit.label}</span>\n );\n }\n\n render() {\n const title = (\n <FormattedMessage\n id='user.settings.sidebar.limitVisibleGMsDMsTitle'\n defaultMessage='Number of direct messages to show'\n />\n );\n\n if (!this.props.active) {\n return (\n <SettingItemMin\n title={title}\n describe={this.renderDescription()}\n section='limitVisibleGMsDMs'\n updateSection={this.props.updateSection}\n />\n );\n }\n\n return (\n <SettingItemMax\n title={title}\n inputs={\n <fieldset>\n <legend className='form-legend hidden-label'>\n {title}\n </legend>\n <ReactSelect\n className='react-select'\n classNamePrefix='react-select'\n id='limitVisibleGMsDMs'\n options={limits}\n clearable={false}\n onChange={this.handleChange}\n value={this.state.limit}\n isSearchable={false}\n menuPortalTarget={document.body}\n styles={reactStyles}\n />\n <div className='mt-5'>\n <FormattedMessage\n id='user.settings.sidebar.limitVisibleGMsDMsDesc'\n defaultMessage='You can also change these settings in the direct messages sidebar menu.'\n />\n </div>\n </fieldset>\n }\n submit={this.handleSubmit}\n saving={this.state.isSaving}\n updateSection={this.props.updateSection}\n />\n );\n }\n}\n\nconst reactStyles = {\n menuPortal: (provided: React.CSSProperties) => ({\n ...provided,\n zIndex: 9999,\n }),\n};\n","// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.\n// See LICENSE.txt for license information.\n\nimport {connect} from 'react-redux';\n\nimport {savePreferences} from 'mattermost-redux/actions/preferences';\nimport {Preferences} from 'mattermost-redux/constants';\nimport {getInt} from 'mattermost-redux/selectors/entities/preferences';\nimport {getCurrentUserId} from 'mattermost-redux/selectors/entities/users';\n\nimport {GlobalState} from 'types/store';\n\nimport LimitVisibleGMsDMs from './limit_visible_gms_dms';\n\nfunction mapStateToProps(state: GlobalState) {\n return {\n currentUserId: getCurrentUserId(state),\n dmGmLimit: getInt(state, Preferences.CATEGORY_SIDEBAR_SETTINGS, Preferences.LIMIT_VISIBLE_DMS_GMS, 20),\n };\n}\n\nconst mapDispatchToProps = {\n savePreferences,\n};\n\nexport default connect(mapStateToProps, mapDispatchToProps)(LimitVisibleGMsDMs);\n","// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.\n// See LICENSE.txt for license information.\n\nimport React from 'react';\nimport {FormattedMessage} from 'react-intl';\n\nimport LocalizedIcon from 'components/localized_icon';\n\nimport {t} from 'utils/i18n';\n\nimport ShowUnreadsCategory from './show_unreads_category';\nimport LimitVisibleGMsDMs from './limit_visible_gms_dms';\n\nexport interface Props {\n updateSection: (section: string) => void;\n activeSection: string;\n closeModal: () => void;\n collapseModal: () => void;\n}\n\nexport default function UserSettingsSidebar(props: Props): JSX.Element {\n return (\n <div>\n <div className='modal-header'>\n <button\n id='closeButton'\n type='button'\n className='close'\n data-dismiss='modal'\n aria-label='Close'\n onClick={props.closeModal}\n >\n <span aria-hidden='true'>{'×'}</span>\n </button>\n <h4 className='modal-title'>\n <div\n className='modal-back'\n onClick={props.collapseModal}\n >\n <LocalizedIcon\n className='fa fa-angle-left'\n title={{id: t('generic_icons.collapse'), defaultMessage: 'Collapse Icon'}}\n />\n </div>\n <FormattedMessage\n id='user.settings.sidebar.title'\n defaultMessage='Sidebar Settings'\n />\n </h4>\n </div>\n <div\n id='sidebarTitle'\n className='user-settings'\n >\n <h3 className='tab-header'>\n <FormattedMessage\n id='user.settings.sidebar.title'\n defaultMessage='Sidebar Settings'\n />\n </h3>\n <div className='divider-dark first'/>\n <ShowUnreadsCategory\n active={props.activeSection === 'showUnreadsCategory'}\n updateSection={props.updateSection}\n />\n <div className='divider-dark'/>\n <LimitVisibleGMsDMs\n active={props.activeSection === 'limitVisibleGMsDMs'}\n updateSection={props.updateSection}\n />\n <div className='divider-dark'/>\n </div>\n </div>\n );\n}\n","// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.\n// See LICENSE.txt for license information.\n\nimport UserSettingsSidebar from './user_settings_sidebar';\n\nexport default UserSettingsSidebar;\n","// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.\n// See LICENSE.txt for license information.\n\nimport React from 'react';\n\nimport {UserProfile} from 'mattermost-redux/types/users';\n\nimport AdvancedTab from './advanced';\nimport DisplayTab from './display';\nimport GeneralTab from './general';\nimport NotificationsTab from './notifications';\nimport SecurityTab from './security';\nimport SidebarTab from './sidebar';\n\nexport type Props = {\n user: UserProfile;\n activeTab?: string;\n activeSection: string;\n updateSection: (section: string) => void;\n updateTab: (notifications: string) => void;\n closeModal: () => void;\n collapseModal: () => void;\n setEnforceFocus: () => void;\n setRequireConfirm: () => void;\n};\n\nexport default class UserSettings extends React.PureComponent<Props> {\n render() {\n if (this.props.activeTab === 'profile') {\n return (\n <div>\n <GeneralTab\n user={this.props.user}\n activeSection={this.props.activeSection}\n updateSection={this.props.updateSection}\n updateTab={this.props.updateTab}\n closeModal={this.props.closeModal}\n collapseModal={this.props.collapseModal}\n />\n </div>\n );\n } else if (this.props.activeTab === 'security') {\n return (\n <div>\n <SecurityTab\n user={this.props.user}\n activeSection={this.props.activeSection}\n updateSection={this.props.updateSection}\n closeModal={this.props.closeModal}\n collapseModal={this.props.collapseModal}\n setRequireConfirm={this.props.setRequireConfirm}\n />\n </div>\n );\n } else if (this.props.activeTab === 'notifications') {\n return (\n <div>\n <NotificationsTab\n user={this.props.user}\n activeSection={this.props.activeSection}\n updateSection={this.props.updateSection}\n closeModal={this.props.closeModal}\n collapseModal={this.props.collapseModal}\n />\n </div>\n );\n } else if (this.props.activeTab === 'display') {\n return (\n <div>\n <DisplayTab\n user={this.props.user}\n activeSection={this.props.activeSection}\n updateSection={this.props.updateSection}\n closeModal={this.props.closeModal}\n collapseModal={this.props.collapseModal}\n setEnforceFocus={this.props.setEnforceFocus}\n setRequireConfirm={this.props.setRequireConfirm}\n />\n </div>\n );\n } else if (this.props.activeTab === 'sidebar') {\n return (\n <div>\n <SidebarTab\n activeSection={this.props.activeSection}\n updateSection={this.props.updateSection}\n closeModal={this.props.closeModal}\n collapseModal={this.props.collapseModal}\n />\n </div>\n );\n } else if (this.props.activeTab === 'advanced') {\n return (\n <div>\n <AdvancedTab\n activeSection={this.props.activeSection}\n updateSection={this.props.updateSection}\n closeModal={this.props.closeModal}\n collapseModal={this.props.collapseModal}\n />\n </div>\n );\n }\n\n return <div/>;\n }\n}\n","// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.\n// See LICENSE.txt for license information.\n\nimport {connect} from 'react-redux';\n\nimport {getCurrentUser} from 'mattermost-redux/selectors/entities/users';\nimport {GlobalState} from 'mattermost-redux/types/store';\n\nimport UserSettings from './user_settings';\n\nfunction mapStateToProps(state: GlobalState) {\n return {\n user: getCurrentUser(state),\n };\n}\n\nexport default connect(mapStateToProps)(UserSettings);\n","// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.\n// See LICENSE.txt for license information.\n\nimport {getCurrentUser} from 'mattermost-redux/selectors/entities/users';\nimport {getUserTimezone} from 'mattermost-redux/selectors/entities/timezone';\n\nimport {DispatchFunc, GetStateFunc} from 'mattermost-redux/types/actions';\n\nimport {updateMe} from './users';\nexport function autoUpdateTimezone(deviceTimezone: string) {\n return async (dispatch: DispatchFunc, getState: GetStateFunc) => {\n const currentUer = getCurrentUser(getState());\n const currentTimezone = getUserTimezone(getState(), currentUer.id);\n const newTimezoneExists = currentTimezone.automaticTimezone !== deviceTimezone;\n\n if (currentTimezone.useAutomaticTimezone && newTimezoneExists) {\n const timezone = {\n useAutomaticTimezone: 'true',\n automaticTimezone: deviceTimezone,\n manualTimezone: currentTimezone.manualTimezone,\n };\n\n const updatedUser = {\n ...currentUer,\n timezone,\n };\n\n updateMe(updatedUser)(dispatch, getState);\n }\n };\n}\n"],"sourceRoot":""}