diff --git a/webapp/channels/package.json b/webapp/channels/package.json
index b15fb121f1..fc0a7ddef2 100644
--- a/webapp/channels/package.json
+++ b/webapp/channels/package.json
@@ -163,7 +163,7 @@
"jest-junit": "12.2.0",
"jest-styled-components": "7.1.1",
"jest-watch-typeahead": "0.6.4",
- "mmjstool": "github:mattermost/mattermost-utilities#d88289ce1d30da1936d9a17e9bed0cdb52de0a10",
+ "mmjstool": "github:mattermost/mattermost-utilities#83b1b311972b8f5e750aae4019457a40abb5aa44",
"nock": "13.2.8",
"prettier": "2.3.2",
"react-router-enzyme-context": "1.2.0",
diff --git a/webapp/channels/src/components/__snapshots__/searchable_channel_list.test.tsx.snap b/webapp/channels/src/components/__snapshots__/searchable_channel_list.test.tsx.snap
index bc93201554..ac38d23951 100644
--- a/webapp/channels/src/components/__snapshots__/searchable_channel_list.test.tsx.snap
+++ b/webapp/channels/src/components/__snapshots__/searchable_channel_list.test.tsx.snap
@@ -20,20 +20,8 @@ exports[`components/SearchableChannelList should match init snapshot 1`] = `
className="form-control filter-textbox"
clearable={true}
id="searchChannelsTextbox"
- inputComponent={
- Object {
- "$$typeof": Symbol(react.forward_ref),
- "render": [Function],
- }
- }
onClear={[Function]}
onInput={[Function]}
- placeholder={
- Object {
- "defaultMessage": "Search channels",
- "id": "filtered_channels_list.search",
- }
- }
value=""
/>
diff --git a/webapp/channels/src/components/browse_channels/__snapshots__/browse_channels.test.tsx.snap b/webapp/channels/src/components/browse_channels/__snapshots__/browse_channels.test.tsx.snap
index d19cca0fca..5c64f04fe7 100644
--- a/webapp/channels/src/components/browse_channels/__snapshots__/browse_channels.test.tsx.snap
+++ b/webapp/channels/src/components/browse_channels/__snapshots__/browse_channels.test.tsx.snap
@@ -43,7 +43,7 @@ exports[`components/BrowseChannels should match snapshot and state 1`] = `
onExited={[Function]}
show={true}
>
- {
const password = emailPasswordInput.current?.value;
if (!password) {
- setPasswordError(localizeMessage('claim.email_to_ldap.pwdError', 'Please enter your password.'));
+ setPasswordError(formatMessage({id: 'claim.email_to_ldap.pwdError', defaultMessage: 'Please enter your password.'}));
setLdapError('');
setLdapPasswordError('');
setServerError('');
@@ -61,7 +59,7 @@ const EmailToLDAP = ({email, siteName, ldapLoginFieldName}: Props) => {
const ldapId = ldapIdInput.current?.value.trim();
if (!ldapId) {
- setLdapError(localizeMessage('claim.email_to_ldap.ldapIdError', 'Please enter your AD/LDAP ID.'));
+ setLdapError(formatMessage({id: 'claim.email_to_ldap.ldapIdError', defaultMessage: 'Please enter your AD/LDAP ID.'}));
setPasswordError('');
setLdapPasswordError('');
setServerError('');
@@ -70,7 +68,7 @@ const EmailToLDAP = ({email, siteName, ldapLoginFieldName}: Props) => {
const ldapPassword = ldapPasswordInput.current?.value;
if (!ldapPassword) {
- setLdapPasswordError(localizeMessage('claim.email_to_ldap.ldapPasswordError', 'Please enter your AD/LDAP password.'));
+ setLdapPasswordError(formatMessage({id: 'claim.email_to_ldap.ldapPasswordError', defaultMessage: 'Please enter your AD/LDAP password.'}));
setLdapError('');
setPasswordError('');
setServerError('');
@@ -126,15 +124,14 @@ const EmailToLDAP = ({email, siteName, ldapLoginFieldName}: Props) => {
);
};
- const loginPlaceholder = ldapLoginFieldName || localizeMessage('claim.email_to_ldap.ldapId', 'AD/LDAP ID');
- const titleMessage = {id: t('claim.email_to_ldap.title'), defaultMessage: 'Switch Email/Password Account to AD/LDAP'};
+ const loginPlaceholder = ldapLoginFieldName || formatMessage({id: 'claim.email_to_ldap.ldapId', defaultMessage: 'AD/LDAP ID'});
if (showMfa) {
return (
);
@@ -212,7 +209,7 @@ const EmailToLDAP = ({email, siteName, ldapLoginFieldName}: Props) => {
name='ldapPassword'
ref={ldapPasswordInput}
autoComplete='off'
- placeholder={formatMessage({id: t('claim.email_to_ldap.ldapPwd'), defaultMessage: 'AD/LDAP Password'})}
+ placeholder={formatMessage({id: 'claim.email_to_ldap.ldapPwd', defaultMessage: 'AD/LDAP Password'})}
spellCheck='false'
/>
diff --git a/webapp/channels/src/components/claim/components/email_to_oauth.tsx b/webapp/channels/src/components/claim/components/email_to_oauth.tsx
index 95c99e1731..0bcc38f110 100644
--- a/webapp/channels/src/components/claim/components/email_to_oauth.tsx
+++ b/webapp/channels/src/components/claim/components/email_to_oauth.tsx
@@ -12,8 +12,7 @@ import {emailToOAuth} from 'actions/admin_actions.jsx';
import LoginMfa from 'components/login/login_mfa';
import Constants, {ClaimErrors} from 'utils/constants';
-import {t} from 'utils/i18n';
-import {localizeMessage, toTitleCase} from 'utils/utils';
+import {toTitleCase} from 'utils/utils';
import type {SubmitOptions} from './email_to_ldap';
import ErrorLabel from './error_label';
@@ -37,7 +36,7 @@ const EmailToOAuth = (props: Props) => {
const password = passwordInput.current?.value;
if (!password) {
- setServerError(localizeMessage('claim.email_to_oauth.pwdError', 'Please enter your password.'));
+ setServerError(formatMessage({id: 'claim.email_to_oauth.pwdError', defaultMessage: 'Please enter your password.'}));
return;
}
@@ -72,17 +71,13 @@ const EmailToOAuth = (props: Props) => {
const type = (props.newType === Constants.SAML_SERVICE ? Constants.SAML_SERVICE.toUpperCase() : toTitleCase(props.newType || ''));
const uiType = `${type} SSO`;
- const titleMessage = {
- id: t('claim.email_to_oauth.title'),
- defaultMessage: 'Switch Email/Password Account to {uiType}',
- };
if (showMfa) {
return (
);
diff --git a/webapp/channels/src/components/claim/components/ldap_to_email.tsx b/webapp/channels/src/components/claim/components/ldap_to_email.tsx
index f82e31eccb..7f4e46f5ad 100644
--- a/webapp/channels/src/components/claim/components/ldap_to_email.tsx
+++ b/webapp/channels/src/components/claim/components/ldap_to_email.tsx
@@ -3,15 +3,13 @@
import classNames from 'classnames';
import React, {useRef, useState} from 'react';
-import {FormattedMessage} from 'react-intl';
+import {FormattedMessage, useIntl} from 'react-intl';
import type {AuthChangeResponse} from '@mattermost/types/users';
-import LocalizedInput from 'components/localized_input/localized_input';
import LoginMfa from 'components/login/login_mfa';
import {ClaimErrors} from 'utils/constants';
-import {t} from 'utils/i18n';
import {isValidPassword, localizeMessage} from 'utils/utils';
import type {SubmitOptions} from './email_to_ldap';
@@ -38,6 +36,8 @@ const LDAPToEmail = (props: Props) => {
const passwordInput = useRef(null);
const passwordConfirmInput = useRef(null);
+ const {formatMessage} = useIntl();
+
const preSubmit = (e: React.FormEvent) => {
e.preventDefault();
@@ -108,17 +108,12 @@ const LDAPToEmail = (props: Props) => {
});
};
- const passwordPlaceholder = localizeMessage('claim.ldap_to_email.ldapPwd', 'AD/LDAP Password');
- const titleMessage = {id: t('claim.ldap_to_email.title'), defaultMessage: 'Switch AD/LDAP Account to Email/Password'};
- const placeholderPasswordMessage = {id: t('claim.ldap_to_email.pwd'), defaultMessage: 'Password'};
- const placeholderConfirmMessage = {id: t('claim.ldap_to_email.confirm'), defaultMessage: 'Confirm Password'};
-
if (showMfa) {
return (
);
@@ -145,8 +140,7 @@ const LDAPToEmail = (props: Props) => {
@@ -155,7 +149,7 @@ const LDAPToEmail = (props: Props) => {
className='form-control'
name='ldapPassword'
ref={ldapPasswordInput}
- placeholder={passwordPlaceholder}
+ placeholder={formatMessage({id: 'claim.ldap_to_email.ldapPwd', defaultMessage: 'AD/LDAP Password'})}
spellCheck='false'
/>
@@ -167,23 +161,23 @@ const LDAPToEmail = (props: Props) => {
/>
-
-
diff --git a/webapp/channels/src/components/header_footer_route/content_layouts/column.tsx b/webapp/channels/src/components/header_footer_route/content_layouts/column.tsx
index c529e41ddc..2136c66150 100644
--- a/webapp/channels/src/components/header_footer_route/content_layouts/column.tsx
+++ b/webapp/channels/src/components/header_footer_route/content_layouts/column.tsx
@@ -1,15 +1,15 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
-import React from 'react';
+import React, {type ReactNode} from 'react';
import Constants from 'utils/constants';
import './column.scss';
type ColumnProps = {
- title: string;
- message: string;
+ title: ReactNode;
+ message: ReactNode;
SVGElement?: React.ReactNode;
extraContent?: React.ReactNode;
onEnterKeyDown?: (e: React.KeyboardEvent) => void;
diff --git a/webapp/channels/src/components/localized_input/__snapshots__/localized_input.test.tsx.snap b/webapp/channels/src/components/localized_input/__snapshots__/localized_input.test.tsx.snap
deleted file mode 100644
index 935af0b0c4..0000000000
--- a/webapp/channels/src/components/localized_input/__snapshots__/localized_input.test.tsx.snap
+++ /dev/null
@@ -1,22 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`components/localized_input/localized_input should match snapshot 1`] = `
-
-
-
-`;
diff --git a/webapp/channels/src/components/localized_input/localized_input.test.tsx b/webapp/channels/src/components/localized_input/localized_input.test.tsx
deleted file mode 100644
index aed53290b6..0000000000
--- a/webapp/channels/src/components/localized_input/localized_input.test.tsx
+++ /dev/null
@@ -1,55 +0,0 @@
-// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
-// See LICENSE.txt for license information.
-
-import {mount} from 'enzyme';
-import React from 'react';
-import {IntlProvider} from 'react-intl';
-
-import {mountWithIntl} from 'tests/helpers/intl-test-helper';
-
-import LocalizedInput from './localized_input';
-
-describe('components/localized_input/localized_input', () => {
- const baseProps = {
- className: 'test-class',
- onChange: jest.fn(),
- placeholder: {id: 'test.placeholder', defaultMessage: 'placeholder to test'},
- value: 'test value',
- };
-
- test('should match snapshot', () => {
- const wrapper = mount(
-
-
- ,
- ).childAt(0);
-
- expect(wrapper).toMatchSnapshot();
- expect(wrapper.find('input').length).toBe(1);
- expect(wrapper.find('input').get(0).props.value).toBe('test value');
- expect(wrapper.find('input').get(0).props.className).toBe('test-class');
- expect(wrapper.find('input').get(0).props.placeholder).toBe('placeholder to test');
- });
-
- it('ref should properly be forwarded', () => {
- const ref = React.createRef();
- const props = {
- ...baseProps,
- ref,
- };
-
- const wrapper = mountWithIntl(
-
-
- ,
- );
-
- expect(ref.current).toBe(wrapper.find('input').instance());
- });
-});
diff --git a/webapp/channels/src/components/localized_input/localized_input.tsx b/webapp/channels/src/components/localized_input/localized_input.tsx
deleted file mode 100644
index ba439dc38e..0000000000
--- a/webapp/channels/src/components/localized_input/localized_input.tsx
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
-// See LICENSE.txt for license information.
-
-import type {PrimitiveType, FormatXMLElementFn} from 'intl-messageformat';
-import React from 'react';
-import type {InputHTMLAttributes} from 'react';
-import {useIntl} from 'react-intl';
-import type {MessageDescriptor} from 'react-intl';
-
-export type Props = Omit, 'placeholder'> & {
- placeholder: MessageDescriptor & {
- values?: Record>;
- };
-};
-
-const LocalizedInput = React.forwardRef((props: Props, ref?: React.Ref) => {
- const {
- placeholder: {
- id,
- defaultMessage,
- values,
- },
- ...otherProps
- } = props;
-
- const {formatMessage} = useIntl();
-
- return (
-
- );
-});
-LocalizedInput.displayName = 'LocalizedInput';
-
-export default LocalizedInput;
diff --git a/webapp/channels/src/components/login/login_mfa.tsx b/webapp/channels/src/components/login/login_mfa.tsx
index 6d5ad14e21..bd2a4906ea 100644
--- a/webapp/channels/src/components/login/login_mfa.tsx
+++ b/webapp/channels/src/components/login/login_mfa.tsx
@@ -1,9 +1,8 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
-import React, {useState} from 'react';
+import React, {type ReactNode, useState} from 'react';
import {useIntl} from 'react-intl';
-import type {MessageDescriptor} from 'react-intl';
import type {SubmitOptions} from 'components/claim/components/email_to_ldap';
import ShieldWithCheckmarkSVG from 'components/common/svg_images_components/shield_with_checkmark';
@@ -16,8 +15,8 @@ import './login_mfa.scss';
type LoginMfaProps = {
loginId: string | null;
password: string;
- title?: MessageDescriptor;
- subtitle?: MessageDescriptor;
+ title?: ReactNode;
+ subtitle?: ReactNode;
onSubmit: ({loginId, password, token}: SubmitOptions) => void;
}
@@ -49,8 +48,8 @@ const LoginMfa = ({loginId, password, title, subtitle, onSubmit}: LoginMfaProps)
return (
}
extraContent={(
diff --git a/webapp/channels/src/components/searchable_channel_list.test.tsx b/webapp/channels/src/components/searchable_channel_list.test.tsx
index 9c5589563d..ec3ea1c79e 100644
--- a/webapp/channels/src/components/searchable_channel_list.test.tsx
+++ b/webapp/channels/src/components/searchable_channel_list.test.tsx
@@ -4,7 +4,9 @@
import {shallow} from 'enzyme';
import React from 'react';
-import SearchableChannelList from 'components/searchable_channel_list';
+import {SearchableChannelList} from 'components/searchable_channel_list';
+
+import {type MockIntl} from 'tests/helpers/intl-test-helper';
import {Filter} from './browse_channels/browse_channels';
@@ -26,6 +28,9 @@ describe('components/SearchableChannelList', () => {
rememberHideJoinedChannelsChecked: false,
noResultsText: <>{'no channel found'}>,
filter: Filter.All,
+ intl: {
+ formatMessage: jest.fn(),
+ } as MockIntl,
};
test('should match init snapshot', () => {
diff --git a/webapp/channels/src/components/searchable_channel_list.tsx b/webapp/channels/src/components/searchable_channel_list.tsx
index 3f1e02094d..b6b8e913bb 100644
--- a/webapp/channels/src/components/searchable_channel_list.tsx
+++ b/webapp/channels/src/components/searchable_channel_list.tsx
@@ -3,7 +3,7 @@
import classNames from 'classnames';
import React from 'react';
-import {FormattedMessage} from 'react-intl';
+import {FormattedMessage, injectIntl, type WrappedComponentProps} from 'react-intl';
import {ArchiveOutlineIcon, CheckIcon, ChevronDownIcon, GlobeIcon, LockOutlineIcon, MagnifyIcon, AccountOutlineIcon, GlobeCheckedIcon} from '@mattermost/compass-icons/components';
import type {Channel, ChannelMembership} from '@mattermost/types/channels';
@@ -13,7 +13,6 @@ import {isPrivateChannel} from 'mattermost-redux/utils/channel_utils';
import MagnifyingGlassSVG from 'components/common/svg_images_components/magnifying_glass_svg';
import LoadingScreen from 'components/loading_screen';
-import LocalizedInput from 'components/localized_input/localized_input';
import * as Menu from 'components/menu';
import QuickInput from 'components/quick_input';
import CheckboxCheckedIcon from 'components/widgets/icons/checkbox_checked_icon';
@@ -31,7 +30,7 @@ import {Filter} from './browse_channels/browse_channels';
const NEXT_BUTTON_TIMEOUT_MILLISECONDS = 500;
-type Props = {
+interface Props extends WrappedComponentProps {
channels: Channel[];
channelsPerPage: number;
nextPage: (page: number) => void;
@@ -58,7 +57,7 @@ type State = {
isSearch?: boolean;
}
-export default class SearchableChannelList extends React.PureComponent
{
+export class SearchableChannelList extends React.PureComponent {
private nextTimeoutId: number | NodeJS.Timeout;
private filter: React.RefObject;
private channelListScroll: React.RefObject;
@@ -410,8 +409,7 @@ export default class SearchableChannelList extends React.PureComponent,
+ ,
this.props.changeFilter(Filter.Archived)}
leadingElement={}
@@ -579,3 +578,5 @@ export default class SearchableChannelList extends React.PureComponent {
let nextButton;
let previousButton;
let usersToDisplay;
- const {formatMessage} = this.props.intl;
if (this.props.term || !this.props.users) {
usersToDisplay = this.props.users;
@@ -281,7 +277,6 @@ class SearchableUserList extends React.PureComponent {
if (this.props.renderFilterRow) {
filterRow = this.props.renderFilterRow(this.handleInput);
} else {
- const searchUsersPlaceholder = {id: t('filtered_user_list.search'), defaultMessage: 'Search users'};
filterRow = (
);
diff --git a/webapp/channels/src/components/team_general_tab/team_general_tab.test.tsx b/webapp/channels/src/components/team_general_tab/team_general_tab.test.tsx
index 82f3c156c3..aed275791a 100644
--- a/webapp/channels/src/components/team_general_tab/team_general_tab.test.tsx
+++ b/webapp/channels/src/components/team_general_tab/team_general_tab.test.tsx
@@ -4,16 +4,12 @@
import {shallow} from 'enzyme';
import React from 'react';
import type {ChangeEvent, ComponentProps} from 'react';
-import {type IntlShape} from 'react-intl';
import {GeneralTab} from 'components/team_general_tab/team_general_tab';
+import {type MockIntl} from 'tests/helpers/intl-test-helper';
import {TestHelper} from 'utils/test_helper';
-interface MockIntl extends IntlShape {
- formatMessage: jest.Mock;
-}
-
describe('components/TeamSettings', () => {
const getTeam = jest.fn().mockResolvedValue({data: true});
const patchTeam = jest.fn().mockReturnValue({data: true});
diff --git a/webapp/channels/src/i18n/en.json b/webapp/channels/src/i18n/en.json
index bdaf318aac..a72819bd65 100644
--- a/webapp/channels/src/i18n/en.json
+++ b/webapp/channels/src/i18n/en.json
@@ -3061,7 +3061,7 @@
"claim.email_to_oauth.title": "Switch Email/Password Account to {uiType}",
"claim.ldap_to_email.confirm": "Confirm Password",
"claim.ldap_to_email.email": "After switching your authentication method, you will use {email} to login. Your AD/LDAP credentials will no longer allow access to Mattermost.",
- "claim.ldap_to_email.enterLdapPwd": "{ldapPassword}:",
+ "claim.ldap_to_email.enterLdapPwd": "AD/LDAP Password:",
"claim.ldap_to_email.enterPwd": "New email login password:",
"claim.ldap_to_email.ldapPasswordError": "Please enter your AD/LDAP password.",
"claim.ldap_to_email.ldapPwd": "AD/LDAP Password",
@@ -3899,6 +3899,8 @@
"local": "local",
"login_mfa.saving": "Logging in…",
"login_mfa.submit": "Submit",
+ "login_mfa.subtitle": "To complete the sign in process, please enter a token from your smartphone's authenticator",
+ "login_mfa.title": "Enter MFA Token",
"login_mfa.token": "MFA Token",
"login.cardtitle": "Log in",
"login.cardtitle.external": "Log in with one of the following:",
diff --git a/webapp/package-lock.json b/webapp/package-lock.json
index b21ac7fe98..b306616dc3 100644
--- a/webapp/package-lock.json
+++ b/webapp/package-lock.json
@@ -210,7 +210,7 @@
"jest-junit": "12.2.0",
"jest-styled-components": "7.1.1",
"jest-watch-typeahead": "0.6.4",
- "mmjstool": "github:mattermost/mattermost-utilities#d88289ce1d30da1936d9a17e9bed0cdb52de0a10",
+ "mmjstool": "github:mattermost/mattermost-utilities#83b1b311972b8f5e750aae4019457a40abb5aa44",
"nock": "13.2.8",
"prettier": "2.3.2",
"react-router-enzyme-context": "1.2.0",
@@ -16248,8 +16248,8 @@
},
"node_modules/mmjstool": {
"version": "1.0.0",
- "resolved": "git+ssh://git@github.com/mattermost/mattermost-utilities.git#d88289ce1d30da1936d9a17e9bed0cdb52de0a10",
- "integrity": "sha512-Fia3OL1qvMCBy8B9GpZVyqcMz/7NvQfxVJ6KWxegqQt0rSIkqI0f7UveAWGCxD6XoPHPcCCtdvuklBWjBxzgIQ==",
+ "resolved": "git+ssh://git@github.com/mattermost/mattermost-utilities.git#83b1b311972b8f5e750aae4019457a40abb5aa44",
+ "integrity": "sha512-SFAbT+eN1mvgSfRTe8k6IMKVWbhGItTJtxZ+Pt0mX+fe8pakB3MkIkWzHBHVnEDI9Ek9kmQFGF1aZwzKFHXyYQ==",
"dev": true,
"dependencies": {
"estree-walk": "^2.2.0",
@@ -35701,7 +35701,7 @@
"mark.js": "8.11.1",
"marked": "github:mattermost/marked#2ef7f28cc7718e3f551c4ce9ea75fdd7580c2008",
"memoize-one": "6.0.0",
- "mmjstool": "github:mattermost/mattermost-utilities#d88289ce1d30da1936d9a17e9bed0cdb52de0a10",
+ "mmjstool": "github:mattermost/mattermost-utilities#83b1b311972b8f5e750aae4019457a40abb5aa44",
"moment-timezone": "0.5.38",
"nock": "13.2.8",
"p-queue": "7.3.0",
@@ -36349,10 +36349,10 @@
"dev": true
},
"mmjstool": {
- "version": "git+ssh://git@github.com/mattermost/mattermost-utilities.git#d88289ce1d30da1936d9a17e9bed0cdb52de0a10",
- "integrity": "sha512-Fia3OL1qvMCBy8B9GpZVyqcMz/7NvQfxVJ6KWxegqQt0rSIkqI0f7UveAWGCxD6XoPHPcCCtdvuklBWjBxzgIQ==",
+ "version": "git+ssh://git@github.com/mattermost/mattermost-utilities.git#83b1b311972b8f5e750aae4019457a40abb5aa44",
+ "integrity": "sha512-SFAbT+eN1mvgSfRTe8k6IMKVWbhGItTJtxZ+Pt0mX+fe8pakB3MkIkWzHBHVnEDI9Ek9kmQFGF1aZwzKFHXyYQ==",
"dev": true,
- "from": "mmjstool@github:mattermost/mattermost-utilities#d88289ce1d30da1936d9a17e9bed0cdb52de0a10",
+ "from": "mmjstool@github:mattermost/mattermost-utilities#83b1b311972b8f5e750aae4019457a40abb5aa44",
"requires": {
"estree-walk": "^2.2.0",
"filehound": "^1.17.5",