[MM-54848] Remove deprecated LocalizedInput component (#25052)
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
22c9c80cd2
Коммит
e552f6b86a
@@ -163,7 +163,7 @@
|
|||||||
"jest-junit": "12.2.0",
|
"jest-junit": "12.2.0",
|
||||||
"jest-styled-components": "7.1.1",
|
"jest-styled-components": "7.1.1",
|
||||||
"jest-watch-typeahead": "0.6.4",
|
"jest-watch-typeahead": "0.6.4",
|
||||||
"mmjstool": "github:mattermost/mattermost-utilities#d88289ce1d30da1936d9a17e9bed0cdb52de0a10",
|
"mmjstool": "github:mattermost/mattermost-utilities#83b1b311972b8f5e750aae4019457a40abb5aa44",
|
||||||
"nock": "13.2.8",
|
"nock": "13.2.8",
|
||||||
"prettier": "2.3.2",
|
"prettier": "2.3.2",
|
||||||
"react-router-enzyme-context": "1.2.0",
|
"react-router-enzyme-context": "1.2.0",
|
||||||
|
|||||||
@@ -20,20 +20,8 @@ exports[`components/SearchableChannelList should match init snapshot 1`] = `
|
|||||||
className="form-control filter-textbox"
|
className="form-control filter-textbox"
|
||||||
clearable={true}
|
clearable={true}
|
||||||
id="searchChannelsTextbox"
|
id="searchChannelsTextbox"
|
||||||
inputComponent={
|
|
||||||
Object {
|
|
||||||
"$$typeof": Symbol(react.forward_ref),
|
|
||||||
"render": [Function],
|
|
||||||
}
|
|
||||||
}
|
|
||||||
onClear={[Function]}
|
onClear={[Function]}
|
||||||
onInput={[Function]}
|
onInput={[Function]}
|
||||||
placeholder={
|
|
||||||
Object {
|
|
||||||
"defaultMessage": "Search channels",
|
|
||||||
"id": "filtered_channels_list.search",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
value=""
|
value=""
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ exports[`components/BrowseChannels should match snapshot and state 1`] = `
|
|||||||
onExited={[Function]}
|
onExited={[Function]}
|
||||||
show={true}
|
show={true}
|
||||||
>
|
>
|
||||||
<SearchableChannelList
|
<injectIntl(SearchableChannelList)
|
||||||
canShowArchivedChannels={true}
|
canShowArchivedChannels={true}
|
||||||
changeFilter={[Function]}
|
changeFilter={[Function]}
|
||||||
channels={
|
channels={
|
||||||
|
|||||||
@@ -12,8 +12,6 @@ import {emailToLdap} from 'actions/admin_actions.jsx';
|
|||||||
import LoginMfa from 'components/login/login_mfa';
|
import LoginMfa from 'components/login/login_mfa';
|
||||||
|
|
||||||
import {ClaimErrors} from 'utils/constants';
|
import {ClaimErrors} from 'utils/constants';
|
||||||
import {t} from 'utils/i18n';
|
|
||||||
import {localizeMessage} from 'utils/utils';
|
|
||||||
|
|
||||||
import ErrorLabel from './error_label';
|
import ErrorLabel from './error_label';
|
||||||
|
|
||||||
@@ -52,7 +50,7 @@ const EmailToLDAP = ({email, siteName, ldapLoginFieldName}: Props) => {
|
|||||||
|
|
||||||
const password = emailPasswordInput.current?.value;
|
const password = emailPasswordInput.current?.value;
|
||||||
if (!password) {
|
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('');
|
setLdapError('');
|
||||||
setLdapPasswordError('');
|
setLdapPasswordError('');
|
||||||
setServerError('');
|
setServerError('');
|
||||||
@@ -61,7 +59,7 @@ const EmailToLDAP = ({email, siteName, ldapLoginFieldName}: Props) => {
|
|||||||
|
|
||||||
const ldapId = ldapIdInput.current?.value.trim();
|
const ldapId = ldapIdInput.current?.value.trim();
|
||||||
if (!ldapId) {
|
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('');
|
setPasswordError('');
|
||||||
setLdapPasswordError('');
|
setLdapPasswordError('');
|
||||||
setServerError('');
|
setServerError('');
|
||||||
@@ -70,7 +68,7 @@ const EmailToLDAP = ({email, siteName, ldapLoginFieldName}: Props) => {
|
|||||||
|
|
||||||
const ldapPassword = ldapPasswordInput.current?.value;
|
const ldapPassword = ldapPasswordInput.current?.value;
|
||||||
if (!ldapPassword) {
|
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('');
|
setLdapError('');
|
||||||
setPasswordError('');
|
setPasswordError('');
|
||||||
setServerError('');
|
setServerError('');
|
||||||
@@ -126,15 +124,14 @@ const EmailToLDAP = ({email, siteName, ldapLoginFieldName}: Props) => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const loginPlaceholder = ldapLoginFieldName || localizeMessage('claim.email_to_ldap.ldapId', 'AD/LDAP ID');
|
const loginPlaceholder = ldapLoginFieldName || formatMessage({id: 'claim.email_to_ldap.ldapId', defaultMessage: 'AD/LDAP ID'});
|
||||||
const titleMessage = {id: t('claim.email_to_ldap.title'), defaultMessage: 'Switch Email/Password Account to AD/LDAP'};
|
|
||||||
|
|
||||||
if (showMfa) {
|
if (showMfa) {
|
||||||
return (
|
return (
|
||||||
<LoginMfa
|
<LoginMfa
|
||||||
loginId={email}
|
loginId={email}
|
||||||
password={password}
|
password={password}
|
||||||
title={titleMessage}
|
title={formatMessage({id: 'claim.email_to_ldap.title', defaultMessage: 'Switch Email/Password Account to AD/LDAP'})}
|
||||||
onSubmit={submit}
|
onSubmit={submit}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
@@ -212,7 +209,7 @@ const EmailToLDAP = ({email, siteName, ldapLoginFieldName}: Props) => {
|
|||||||
name='ldapPassword'
|
name='ldapPassword'
|
||||||
ref={ldapPasswordInput}
|
ref={ldapPasswordInput}
|
||||||
autoComplete='off'
|
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'
|
spellCheck='false'
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -12,8 +12,7 @@ import {emailToOAuth} from 'actions/admin_actions.jsx';
|
|||||||
import LoginMfa from 'components/login/login_mfa';
|
import LoginMfa from 'components/login/login_mfa';
|
||||||
|
|
||||||
import Constants, {ClaimErrors} from 'utils/constants';
|
import Constants, {ClaimErrors} from 'utils/constants';
|
||||||
import {t} from 'utils/i18n';
|
import {toTitleCase} from 'utils/utils';
|
||||||
import {localizeMessage, toTitleCase} from 'utils/utils';
|
|
||||||
|
|
||||||
import type {SubmitOptions} from './email_to_ldap';
|
import type {SubmitOptions} from './email_to_ldap';
|
||||||
import ErrorLabel from './error_label';
|
import ErrorLabel from './error_label';
|
||||||
@@ -37,7 +36,7 @@ const EmailToOAuth = (props: Props) => {
|
|||||||
|
|
||||||
const password = passwordInput.current?.value;
|
const password = passwordInput.current?.value;
|
||||||
if (!password) {
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -72,17 +71,13 @@ const EmailToOAuth = (props: Props) => {
|
|||||||
|
|
||||||
const type = (props.newType === Constants.SAML_SERVICE ? Constants.SAML_SERVICE.toUpperCase() : toTitleCase(props.newType || ''));
|
const type = (props.newType === Constants.SAML_SERVICE ? Constants.SAML_SERVICE.toUpperCase() : toTitleCase(props.newType || ''));
|
||||||
const uiType = `${type} SSO`;
|
const uiType = `${type} SSO`;
|
||||||
const titleMessage = {
|
|
||||||
id: t('claim.email_to_oauth.title'),
|
|
||||||
defaultMessage: 'Switch Email/Password Account to {uiType}',
|
|
||||||
};
|
|
||||||
|
|
||||||
if (showMfa) {
|
if (showMfa) {
|
||||||
return (
|
return (
|
||||||
<LoginMfa
|
<LoginMfa
|
||||||
loginId={props.email}
|
loginId={props.email}
|
||||||
password={password}
|
password={password}
|
||||||
title={titleMessage}
|
title={formatMessage({id: 'claim.email_to_oauth.title', defaultMessage: 'Switch Email/Password Account to {uiType}'})}
|
||||||
onSubmit={submit}
|
onSubmit={submit}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -3,15 +3,13 @@
|
|||||||
|
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import React, {useRef, useState} from 'react';
|
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 type {AuthChangeResponse} from '@mattermost/types/users';
|
||||||
|
|
||||||
import LocalizedInput from 'components/localized_input/localized_input';
|
|
||||||
import LoginMfa from 'components/login/login_mfa';
|
import LoginMfa from 'components/login/login_mfa';
|
||||||
|
|
||||||
import {ClaimErrors} from 'utils/constants';
|
import {ClaimErrors} from 'utils/constants';
|
||||||
import {t} from 'utils/i18n';
|
|
||||||
import {isValidPassword, localizeMessage} from 'utils/utils';
|
import {isValidPassword, localizeMessage} from 'utils/utils';
|
||||||
|
|
||||||
import type {SubmitOptions} from './email_to_ldap';
|
import type {SubmitOptions} from './email_to_ldap';
|
||||||
@@ -38,6 +36,8 @@ const LDAPToEmail = (props: Props) => {
|
|||||||
const passwordInput = useRef<HTMLInputElement>(null);
|
const passwordInput = useRef<HTMLInputElement>(null);
|
||||||
const passwordConfirmInput = useRef<HTMLInputElement>(null);
|
const passwordConfirmInput = useRef<HTMLInputElement>(null);
|
||||||
|
|
||||||
|
const {formatMessage} = useIntl();
|
||||||
|
|
||||||
const preSubmit = (e: React.FormEvent) => {
|
const preSubmit = (e: React.FormEvent) => {
|
||||||
e.preventDefault();
|
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) {
|
if (showMfa) {
|
||||||
return (
|
return (
|
||||||
<LoginMfa
|
<LoginMfa
|
||||||
loginId={props.email}
|
loginId={props.email}
|
||||||
password={password}
|
password={password}
|
||||||
title={titleMessage}
|
title={formatMessage({id: 'claim.ldap_to_email.title', defaultMessage: 'Switch AD/LDAP Account to Email/Password'})}
|
||||||
onSubmit={submit}
|
onSubmit={submit}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
@@ -145,8 +140,7 @@ const LDAPToEmail = (props: Props) => {
|
|||||||
<p>
|
<p>
|
||||||
<FormattedMessage
|
<FormattedMessage
|
||||||
id='claim.ldap_to_email.enterLdapPwd'
|
id='claim.ldap_to_email.enterLdapPwd'
|
||||||
defaultMessage='{ldapPassword}:'
|
defaultMessage='AD/LDAP Password:'
|
||||||
values={{ldapPassword: passwordPlaceholder}}
|
|
||||||
/>
|
/>
|
||||||
</p>
|
</p>
|
||||||
<div className={classNames('form-group', {'has-error': ldapPasswordError})}>
|
<div className={classNames('form-group', {'has-error': ldapPasswordError})}>
|
||||||
@@ -155,7 +149,7 @@ const LDAPToEmail = (props: Props) => {
|
|||||||
className='form-control'
|
className='form-control'
|
||||||
name='ldapPassword'
|
name='ldapPassword'
|
||||||
ref={ldapPasswordInput}
|
ref={ldapPasswordInput}
|
||||||
placeholder={passwordPlaceholder}
|
placeholder={formatMessage({id: 'claim.ldap_to_email.ldapPwd', defaultMessage: 'AD/LDAP Password'})}
|
||||||
spellCheck='false'
|
spellCheck='false'
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@@ -167,23 +161,23 @@ const LDAPToEmail = (props: Props) => {
|
|||||||
/>
|
/>
|
||||||
</p>
|
</p>
|
||||||
<div className={classNames('form-group', {'has-error': passwordError})}>
|
<div className={classNames('form-group', {'has-error': passwordError})}>
|
||||||
<LocalizedInput
|
<input
|
||||||
|
ref={passwordInput}
|
||||||
type='password'
|
type='password'
|
||||||
className='form-control'
|
className='form-control'
|
||||||
name='password'
|
name='password'
|
||||||
ref={passwordInput}
|
placeholder={formatMessage({id: 'claim.ldap_to_email.pwd', defaultMessage: 'Password'})}
|
||||||
placeholder={placeholderPasswordMessage}
|
|
||||||
spellCheck='false'
|
spellCheck='false'
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<ErrorLabel errorText={passwordError}/>
|
<ErrorLabel errorText={passwordError}/>
|
||||||
<div className={classNames('form-group', {'has-error': confirmError})}>
|
<div className={classNames('form-group', {'has-error': confirmError})}>
|
||||||
<LocalizedInput
|
<input
|
||||||
|
ref={passwordConfirmInput}
|
||||||
type='password'
|
type='password'
|
||||||
className='form-control'
|
className='form-control'
|
||||||
name='passwordconfirm'
|
name='passwordconfirm'
|
||||||
ref={passwordConfirmInput}
|
placeholder={formatMessage({id: 'claim.ldap_to_email.confirm', defaultMessage: 'Confirm Password'})}
|
||||||
placeholder={placeholderConfirmMessage}
|
|
||||||
spellCheck='false'
|
spellCheck='false'
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,15 +1,15 @@
|
|||||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||||
// See LICENSE.txt for license information.
|
// See LICENSE.txt for license information.
|
||||||
|
|
||||||
import React from 'react';
|
import React, {type ReactNode} from 'react';
|
||||||
|
|
||||||
import Constants from 'utils/constants';
|
import Constants from 'utils/constants';
|
||||||
|
|
||||||
import './column.scss';
|
import './column.scss';
|
||||||
|
|
||||||
type ColumnProps = {
|
type ColumnProps = {
|
||||||
title: string;
|
title: ReactNode;
|
||||||
message: string;
|
message: ReactNode;
|
||||||
SVGElement?: React.ReactNode;
|
SVGElement?: React.ReactNode;
|
||||||
extraContent?: React.ReactNode;
|
extraContent?: React.ReactNode;
|
||||||
onEnterKeyDown?: (e: React.KeyboardEvent<HTMLInputElement>) => void;
|
onEnterKeyDown?: (e: React.KeyboardEvent<HTMLInputElement>) => void;
|
||||||
|
|||||||
@@ -1,22 +0,0 @@
|
|||||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
||||||
|
|
||||||
exports[`components/localized_input/localized_input should match snapshot 1`] = `
|
|
||||||
<LocalizedInput
|
|
||||||
className="test-class"
|
|
||||||
onChange={[MockFunction]}
|
|
||||||
placeholder={
|
|
||||||
Object {
|
|
||||||
"defaultMessage": "placeholder to test",
|
|
||||||
"id": "test.placeholder",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
value="test value"
|
|
||||||
>
|
|
||||||
<input
|
|
||||||
className="test-class"
|
|
||||||
onChange={[MockFunction]}
|
|
||||||
placeholder="placeholder to test"
|
|
||||||
value="test value"
|
|
||||||
/>
|
|
||||||
</LocalizedInput>
|
|
||||||
`;
|
|
||||||
@@ -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(
|
|
||||||
<IntlProvider
|
|
||||||
locale='en'
|
|
||||||
messages={{}}
|
|
||||||
>
|
|
||||||
<LocalizedInput {...baseProps}/>
|
|
||||||
</IntlProvider>,
|
|
||||||
).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<HTMLInputElement>();
|
|
||||||
const props = {
|
|
||||||
...baseProps,
|
|
||||||
ref,
|
|
||||||
};
|
|
||||||
|
|
||||||
const wrapper = mountWithIntl(
|
|
||||||
<IntlProvider
|
|
||||||
locale='en'
|
|
||||||
messages={{}}
|
|
||||||
>
|
|
||||||
<LocalizedInput {...props}/>
|
|
||||||
</IntlProvider>,
|
|
||||||
);
|
|
||||||
|
|
||||||
expect(ref.current).toBe(wrapper.find('input').instance());
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -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<InputHTMLAttributes<HTMLInputElement>, 'placeholder'> & {
|
|
||||||
placeholder: MessageDescriptor & {
|
|
||||||
values?: Record<string, PrimitiveType | FormatXMLElementFn<string, string>>;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
const LocalizedInput = React.forwardRef((props: Props, ref?: React.Ref<HTMLInputElement>) => {
|
|
||||||
const {
|
|
||||||
placeholder: {
|
|
||||||
id,
|
|
||||||
defaultMessage,
|
|
||||||
values,
|
|
||||||
},
|
|
||||||
...otherProps
|
|
||||||
} = props;
|
|
||||||
|
|
||||||
const {formatMessage} = useIntl();
|
|
||||||
|
|
||||||
return (
|
|
||||||
<input
|
|
||||||
{...otherProps}
|
|
||||||
ref={ref}
|
|
||||||
placeholder={formatMessage({id, defaultMessage}, values)}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
});
|
|
||||||
LocalizedInput.displayName = 'LocalizedInput';
|
|
||||||
|
|
||||||
export default LocalizedInput;
|
|
||||||
@@ -1,9 +1,8 @@
|
|||||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||||
// See LICENSE.txt for license information.
|
// See LICENSE.txt for license information.
|
||||||
|
|
||||||
import React, {useState} from 'react';
|
import React, {type ReactNode, useState} from 'react';
|
||||||
import {useIntl} from 'react-intl';
|
import {useIntl} from 'react-intl';
|
||||||
import type {MessageDescriptor} from 'react-intl';
|
|
||||||
|
|
||||||
import type {SubmitOptions} from 'components/claim/components/email_to_ldap';
|
import type {SubmitOptions} from 'components/claim/components/email_to_ldap';
|
||||||
import ShieldWithCheckmarkSVG from 'components/common/svg_images_components/shield_with_checkmark';
|
import ShieldWithCheckmarkSVG from 'components/common/svg_images_components/shield_with_checkmark';
|
||||||
@@ -16,8 +15,8 @@ import './login_mfa.scss';
|
|||||||
type LoginMfaProps = {
|
type LoginMfaProps = {
|
||||||
loginId: string | null;
|
loginId: string | null;
|
||||||
password: string;
|
password: string;
|
||||||
title?: MessageDescriptor;
|
title?: ReactNode;
|
||||||
subtitle?: MessageDescriptor;
|
subtitle?: ReactNode;
|
||||||
onSubmit: ({loginId, password, token}: SubmitOptions) => void;
|
onSubmit: ({loginId, password, token}: SubmitOptions) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -49,8 +48,8 @@ const LoginMfa = ({loginId, password, title, subtitle, onSubmit}: LoginMfaProps)
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<ColumnLayout
|
<ColumnLayout
|
||||||
title={formatMessage(title || {id: 'login_mfa.title', defaultMessage: 'Enter MFA Token'})}
|
title={title || formatMessage({id: 'login_mfa.title', defaultMessage: 'Enter MFA Token'})}
|
||||||
message={formatMessage(subtitle || {id: 'login_mfa.subtitle', defaultMessage: 'To complete the sign in process, please enter a token from your smartphone\'s authenticator'})}
|
message={subtitle || formatMessage({id: 'login_mfa.subtitle', defaultMessage: 'To complete the sign in process, please enter a token from your smartphone\'s authenticator'})}
|
||||||
SVGElement={<ShieldWithCheckmarkSVG/>}
|
SVGElement={<ShieldWithCheckmarkSVG/>}
|
||||||
extraContent={(
|
extraContent={(
|
||||||
<div className='login-mfa-form'>
|
<div className='login-mfa-form'>
|
||||||
|
|||||||
@@ -4,7 +4,9 @@
|
|||||||
import {shallow} from 'enzyme';
|
import {shallow} from 'enzyme';
|
||||||
import React from 'react';
|
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';
|
import {Filter} from './browse_channels/browse_channels';
|
||||||
|
|
||||||
@@ -26,6 +28,9 @@ describe('components/SearchableChannelList', () => {
|
|||||||
rememberHideJoinedChannelsChecked: false,
|
rememberHideJoinedChannelsChecked: false,
|
||||||
noResultsText: <>{'no channel found'}</>,
|
noResultsText: <>{'no channel found'}</>,
|
||||||
filter: Filter.All,
|
filter: Filter.All,
|
||||||
|
intl: {
|
||||||
|
formatMessage: jest.fn(),
|
||||||
|
} as MockIntl,
|
||||||
};
|
};
|
||||||
|
|
||||||
test('should match init snapshot', () => {
|
test('should match init snapshot', () => {
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import React from 'react';
|
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 {ArchiveOutlineIcon, CheckIcon, ChevronDownIcon, GlobeIcon, LockOutlineIcon, MagnifyIcon, AccountOutlineIcon, GlobeCheckedIcon} from '@mattermost/compass-icons/components';
|
||||||
import type {Channel, ChannelMembership} from '@mattermost/types/channels';
|
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 MagnifyingGlassSVG from 'components/common/svg_images_components/magnifying_glass_svg';
|
||||||
import LoadingScreen from 'components/loading_screen';
|
import LoadingScreen from 'components/loading_screen';
|
||||||
import LocalizedInput from 'components/localized_input/localized_input';
|
|
||||||
import * as Menu from 'components/menu';
|
import * as Menu from 'components/menu';
|
||||||
import QuickInput from 'components/quick_input';
|
import QuickInput from 'components/quick_input';
|
||||||
import CheckboxCheckedIcon from 'components/widgets/icons/checkbox_checked_icon';
|
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;
|
const NEXT_BUTTON_TIMEOUT_MILLISECONDS = 500;
|
||||||
|
|
||||||
type Props = {
|
interface Props extends WrappedComponentProps {
|
||||||
channels: Channel[];
|
channels: Channel[];
|
||||||
channelsPerPage: number;
|
channelsPerPage: number;
|
||||||
nextPage: (page: number) => void;
|
nextPage: (page: number) => void;
|
||||||
@@ -58,7 +57,7 @@ type State = {
|
|||||||
isSearch?: boolean;
|
isSearch?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class SearchableChannelList extends React.PureComponent<Props, State> {
|
export class SearchableChannelList extends React.PureComponent<Props, State> {
|
||||||
private nextTimeoutId: number | NodeJS.Timeout;
|
private nextTimeoutId: number | NodeJS.Timeout;
|
||||||
private filter: React.RefObject<HTMLInputElement>;
|
private filter: React.RefObject<HTMLInputElement>;
|
||||||
private channelListScroll: React.RefObject<HTMLDivElement>;
|
private channelListScroll: React.RefObject<HTMLDivElement>;
|
||||||
@@ -410,8 +409,7 @@ export default class SearchableChannelList extends React.PureComponent<Props, St
|
|||||||
id='searchChannelsTextbox'
|
id='searchChannelsTextbox'
|
||||||
ref={this.filter}
|
ref={this.filter}
|
||||||
className='form-control filter-textbox'
|
className='form-control filter-textbox'
|
||||||
placeholder={{id: t('filtered_channels_list.search'), defaultMessage: 'Search channels'}}
|
placeholder={this.props.intl.formatMessage({id: 'filtered_channels_list.search', defaultMessage: 'Search channels'})}
|
||||||
inputComponent={LocalizedInput}
|
|
||||||
onInput={this.handleChange}
|
onInput={this.handleChange}
|
||||||
clearable={true}
|
clearable={true}
|
||||||
onClear={this.handleClear}
|
onClear={this.handleClear}
|
||||||
@@ -474,8 +472,9 @@ export default class SearchableChannelList extends React.PureComponent<Props, St
|
|||||||
|
|
||||||
if (this.props.canShowArchivedChannels) {
|
if (this.props.canShowArchivedChannels) {
|
||||||
channelDropdownItems.push(
|
channelDropdownItems.push(
|
||||||
<Menu.Separator/>,
|
<Menu.Separator key='channelsMoreDropdownSeparator'/>,
|
||||||
<Menu.Item
|
<Menu.Item
|
||||||
|
key='channelsMoreDropdownArchived'
|
||||||
id='channelsMoreDropdownArchived'
|
id='channelsMoreDropdownArchived'
|
||||||
onClick={() => this.props.changeFilter(Filter.Archived)}
|
onClick={() => this.props.changeFilter(Filter.Archived)}
|
||||||
leadingElement={<ArchiveOutlineIcon size={16}/>}
|
leadingElement={<ArchiveOutlineIcon size={16}/>}
|
||||||
@@ -579,3 +578,5 @@ export default class SearchableChannelList extends React.PureComponent<Props, St
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default injectIntl(SearchableChannelList);
|
||||||
|
|||||||
@@ -10,12 +10,9 @@ import type {Channel, ChannelMembership} from '@mattermost/types/channels';
|
|||||||
import type {TeamMembership} from '@mattermost/types/teams';
|
import type {TeamMembership} from '@mattermost/types/teams';
|
||||||
import type {UserProfile} from '@mattermost/types/users';
|
import type {UserProfile} from '@mattermost/types/users';
|
||||||
|
|
||||||
import LocalizedInput from 'components/localized_input/localized_input';
|
|
||||||
import QuickInput from 'components/quick_input';
|
import QuickInput from 'components/quick_input';
|
||||||
import UserList from 'components/user_list';
|
import UserList from 'components/user_list';
|
||||||
|
|
||||||
import {t} from 'utils/i18n';
|
|
||||||
|
|
||||||
const NEXT_BUTTON_TIMEOUT = 500;
|
const NEXT_BUTTON_TIMEOUT = 500;
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
@@ -232,7 +229,6 @@ class SearchableUserList extends React.PureComponent<Props, State> {
|
|||||||
let nextButton;
|
let nextButton;
|
||||||
let previousButton;
|
let previousButton;
|
||||||
let usersToDisplay;
|
let usersToDisplay;
|
||||||
const {formatMessage} = this.props.intl;
|
|
||||||
|
|
||||||
if (this.props.term || !this.props.users) {
|
if (this.props.term || !this.props.users) {
|
||||||
usersToDisplay = this.props.users;
|
usersToDisplay = this.props.users;
|
||||||
@@ -281,7 +277,6 @@ class SearchableUserList extends React.PureComponent<Props, State> {
|
|||||||
if (this.props.renderFilterRow) {
|
if (this.props.renderFilterRow) {
|
||||||
filterRow = this.props.renderFilterRow(this.handleInput);
|
filterRow = this.props.renderFilterRow(this.handleInput);
|
||||||
} else {
|
} else {
|
||||||
const searchUsersPlaceholder = {id: t('filtered_user_list.search'), defaultMessage: 'Search users'};
|
|
||||||
filterRow = (
|
filterRow = (
|
||||||
<div className='col-xs-12'>
|
<div className='col-xs-12'>
|
||||||
<label
|
<label
|
||||||
@@ -294,14 +289,13 @@ class SearchableUserList extends React.PureComponent<Props, State> {
|
|||||||
/>
|
/>
|
||||||
</label>
|
</label>
|
||||||
<QuickInput
|
<QuickInput
|
||||||
id='searchUsersInput'
|
|
||||||
ref={this.filterRef}
|
ref={this.filterRef}
|
||||||
|
id='searchUsersInput'
|
||||||
className='form-control filter-textbox'
|
className='form-control filter-textbox'
|
||||||
placeholder={searchUsersPlaceholder}
|
placeholder={this.props.intl.formatMessage({id: 'filtered_user_list.search', defaultMessage: 'Search users'})}
|
||||||
inputComponent={LocalizedInput}
|
aria-label={this.props.intl.formatMessage({id: 'filtered_user_list.search', defaultMessage: 'Search users'})}
|
||||||
value={this.props.term}
|
|
||||||
onInput={this.handleInput}
|
onInput={this.handleInput}
|
||||||
aria-label={formatMessage(searchUsersPlaceholder).toLowerCase()}
|
value={this.props.term}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -4,16 +4,12 @@
|
|||||||
import {shallow} from 'enzyme';
|
import {shallow} from 'enzyme';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import type {ChangeEvent, ComponentProps} 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 {GeneralTab} from 'components/team_general_tab/team_general_tab';
|
||||||
|
|
||||||
|
import {type MockIntl} from 'tests/helpers/intl-test-helper';
|
||||||
import {TestHelper} from 'utils/test_helper';
|
import {TestHelper} from 'utils/test_helper';
|
||||||
|
|
||||||
interface MockIntl extends IntlShape {
|
|
||||||
formatMessage: jest.Mock;
|
|
||||||
}
|
|
||||||
|
|
||||||
describe('components/TeamSettings', () => {
|
describe('components/TeamSettings', () => {
|
||||||
const getTeam = jest.fn().mockResolvedValue({data: true});
|
const getTeam = jest.fn().mockResolvedValue({data: true});
|
||||||
const patchTeam = jest.fn().mockReturnValue({data: true});
|
const patchTeam = jest.fn().mockReturnValue({data: true});
|
||||||
|
|||||||
@@ -3061,7 +3061,7 @@
|
|||||||
"claim.email_to_oauth.title": "Switch Email/Password Account to {uiType}",
|
"claim.email_to_oauth.title": "Switch Email/Password Account to {uiType}",
|
||||||
"claim.ldap_to_email.confirm": "Confirm Password",
|
"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.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.enterPwd": "New email login password:",
|
||||||
"claim.ldap_to_email.ldapPasswordError": "Please enter your AD/LDAP password.",
|
"claim.ldap_to_email.ldapPasswordError": "Please enter your AD/LDAP password.",
|
||||||
"claim.ldap_to_email.ldapPwd": "AD/LDAP Password",
|
"claim.ldap_to_email.ldapPwd": "AD/LDAP Password",
|
||||||
@@ -3899,6 +3899,8 @@
|
|||||||
"local": "local",
|
"local": "local",
|
||||||
"login_mfa.saving": "Logging in…",
|
"login_mfa.saving": "Logging in…",
|
||||||
"login_mfa.submit": "Submit",
|
"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_mfa.token": "MFA Token",
|
||||||
"login.cardtitle": "Log in",
|
"login.cardtitle": "Log in",
|
||||||
"login.cardtitle.external": "Log in with one of the following:",
|
"login.cardtitle.external": "Log in with one of the following:",
|
||||||
|
|||||||
14
webapp/package-lock.json
сгенерированный
14
webapp/package-lock.json
сгенерированный
@@ -210,7 +210,7 @@
|
|||||||
"jest-junit": "12.2.0",
|
"jest-junit": "12.2.0",
|
||||||
"jest-styled-components": "7.1.1",
|
"jest-styled-components": "7.1.1",
|
||||||
"jest-watch-typeahead": "0.6.4",
|
"jest-watch-typeahead": "0.6.4",
|
||||||
"mmjstool": "github:mattermost/mattermost-utilities#d88289ce1d30da1936d9a17e9bed0cdb52de0a10",
|
"mmjstool": "github:mattermost/mattermost-utilities#83b1b311972b8f5e750aae4019457a40abb5aa44",
|
||||||
"nock": "13.2.8",
|
"nock": "13.2.8",
|
||||||
"prettier": "2.3.2",
|
"prettier": "2.3.2",
|
||||||
"react-router-enzyme-context": "1.2.0",
|
"react-router-enzyme-context": "1.2.0",
|
||||||
@@ -16248,8 +16248,8 @@
|
|||||||
},
|
},
|
||||||
"node_modules/mmjstool": {
|
"node_modules/mmjstool": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "git+ssh://git@github.com/mattermost/mattermost-utilities.git#d88289ce1d30da1936d9a17e9bed0cdb52de0a10",
|
"resolved": "git+ssh://git@github.com/mattermost/mattermost-utilities.git#83b1b311972b8f5e750aae4019457a40abb5aa44",
|
||||||
"integrity": "sha512-Fia3OL1qvMCBy8B9GpZVyqcMz/7NvQfxVJ6KWxegqQt0rSIkqI0f7UveAWGCxD6XoPHPcCCtdvuklBWjBxzgIQ==",
|
"integrity": "sha512-SFAbT+eN1mvgSfRTe8k6IMKVWbhGItTJtxZ+Pt0mX+fe8pakB3MkIkWzHBHVnEDI9Ek9kmQFGF1aZwzKFHXyYQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"estree-walk": "^2.2.0",
|
"estree-walk": "^2.2.0",
|
||||||
@@ -35701,7 +35701,7 @@
|
|||||||
"mark.js": "8.11.1",
|
"mark.js": "8.11.1",
|
||||||
"marked": "github:mattermost/marked#2ef7f28cc7718e3f551c4ce9ea75fdd7580c2008",
|
"marked": "github:mattermost/marked#2ef7f28cc7718e3f551c4ce9ea75fdd7580c2008",
|
||||||
"memoize-one": "6.0.0",
|
"memoize-one": "6.0.0",
|
||||||
"mmjstool": "github:mattermost/mattermost-utilities#d88289ce1d30da1936d9a17e9bed0cdb52de0a10",
|
"mmjstool": "github:mattermost/mattermost-utilities#83b1b311972b8f5e750aae4019457a40abb5aa44",
|
||||||
"moment-timezone": "0.5.38",
|
"moment-timezone": "0.5.38",
|
||||||
"nock": "13.2.8",
|
"nock": "13.2.8",
|
||||||
"p-queue": "7.3.0",
|
"p-queue": "7.3.0",
|
||||||
@@ -36349,10 +36349,10 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"mmjstool": {
|
"mmjstool": {
|
||||||
"version": "git+ssh://git@github.com/mattermost/mattermost-utilities.git#d88289ce1d30da1936d9a17e9bed0cdb52de0a10",
|
"version": "git+ssh://git@github.com/mattermost/mattermost-utilities.git#83b1b311972b8f5e750aae4019457a40abb5aa44",
|
||||||
"integrity": "sha512-Fia3OL1qvMCBy8B9GpZVyqcMz/7NvQfxVJ6KWxegqQt0rSIkqI0f7UveAWGCxD6XoPHPcCCtdvuklBWjBxzgIQ==",
|
"integrity": "sha512-SFAbT+eN1mvgSfRTe8k6IMKVWbhGItTJtxZ+Pt0mX+fe8pakB3MkIkWzHBHVnEDI9Ek9kmQFGF1aZwzKFHXyYQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"from": "mmjstool@github:mattermost/mattermost-utilities#d88289ce1d30da1936d9a17e9bed0cdb52de0a10",
|
"from": "mmjstool@github:mattermost/mattermost-utilities#83b1b311972b8f5e750aae4019457a40abb5aa44",
|
||||||
"requires": {
|
"requires": {
|
||||||
"estree-walk": "^2.2.0",
|
"estree-walk": "^2.2.0",
|
||||||
"filehound": "^1.17.5",
|
"filehound": "^1.17.5",
|
||||||
|
|||||||
Ссылка в новой задаче
Block a user