[WebApp][MM-51266]: Add compass (MUI wrapper components) in common components package (#22942)
* wrap all the components using compass-components with compass-components theme provider Co-authored-by: @michelengelen Co-authored-by: Mattermost Build <build@mattermost.com>
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
a496c14cc2
Коммит
389062193b
@@ -13,9 +13,10 @@
|
||||
"@mattermost/compass-components": "^0.2.12",
|
||||
"@mattermost/compass-icons": "0.1.34",
|
||||
"@mattermost/types": "*",
|
||||
"@mui/base": "5.0.0-alpha.116",
|
||||
"@mui/material": "5.11.7",
|
||||
"@mui/styled-engine-sc": "5.11.0",
|
||||
"@mui/base": "5.0.0-alpha.127",
|
||||
"@mui/material": "5.11.16",
|
||||
"@mui/system": "5.11.16",
|
||||
"@mui/styled-engine-sc": "5.11.11",
|
||||
"@stripe/react-stripe-js": "1.13.0",
|
||||
"@stripe/stripe-js": "1.41.0",
|
||||
"@tippyjs/react": "4.2.6",
|
||||
|
||||
@@ -7,7 +7,7 @@ import {FormattedMessage} from 'react-intl';
|
||||
|
||||
import {useDispatch, useSelector} from 'react-redux';
|
||||
|
||||
import {GenericModal} from '@mattermost/components';
|
||||
import {LegacyGenericModal} from '@mattermost/components';
|
||||
|
||||
import LaptopAlertSVG from 'components/common/svg_images_components/laptop_alert_svg';
|
||||
import {closeModal, openModal} from 'actions/views/modals';
|
||||
@@ -180,7 +180,7 @@ export default function DeleteWorkspaceModal(props: Props) {
|
||||
}
|
||||
|
||||
return (
|
||||
<GenericModal
|
||||
<LegacyGenericModal
|
||||
className='DeleteWorkspaceModal'
|
||||
onExited={handleClickCancel}
|
||||
>
|
||||
@@ -249,6 +249,6 @@ export default function DeleteWorkspaceModal(props: Props) {
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
</GenericModal>
|
||||
</LegacyGenericModal>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
import React from 'react';
|
||||
import {FormattedMessage} from 'react-intl';
|
||||
|
||||
import {GenericModal} from '@mattermost/components';
|
||||
import {LegacyGenericModal} from '@mattermost/components';
|
||||
import {CloudLinks} from 'utils/constants';
|
||||
import CreditCardSvg from 'components/common/svg_images_components/credit_card_svg';
|
||||
import {useControlAirGappedSelfHostedPurchaseModal} from 'components/common/hooks/useControlModal';
|
||||
@@ -15,7 +15,7 @@ export default function AirGappedSelfHostedPurhcaseModal() {
|
||||
const {close} = useControlAirGappedSelfHostedPurchaseModal();
|
||||
|
||||
return (
|
||||
<GenericModal
|
||||
<LegacyGenericModal
|
||||
onExited={close}
|
||||
show={true}
|
||||
className='air-gapped-purchase-modal'
|
||||
@@ -39,6 +39,6 @@ export default function AirGappedSelfHostedPurhcaseModal() {
|
||||
</span>
|
||||
<a href={CloudLinks.SELF_HOSTED_PRICING}>{CloudLinks.SELF_HOSTED_PRICING}</a>
|
||||
</div>
|
||||
</GenericModal>
|
||||
</LegacyGenericModal>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`components/drafts/draft_actions/delete_draft_modal should have called onConfirm 1`] = `
|
||||
<GenericModal
|
||||
<LegacyGenericModal
|
||||
autoCloseOnCancelButton={true}
|
||||
autoCloseOnConfirmButton={true}
|
||||
bodyPadding={true}
|
||||
@@ -39,11 +39,11 @@ exports[`components/drafts/draft_actions/delete_draft_modal should have called o
|
||||
}
|
||||
}
|
||||
/>
|
||||
</GenericModal>
|
||||
</LegacyGenericModal>
|
||||
`;
|
||||
|
||||
exports[`components/drafts/draft_actions/delete_draft_modal should have called onExited 1`] = `
|
||||
<GenericModal
|
||||
<LegacyGenericModal
|
||||
autoCloseOnCancelButton={true}
|
||||
autoCloseOnConfirmButton={true}
|
||||
bodyPadding={true}
|
||||
@@ -81,7 +81,7 @@ exports[`components/drafts/draft_actions/delete_draft_modal should have called o
|
||||
}
|
||||
}
|
||||
/>
|
||||
</GenericModal>
|
||||
</LegacyGenericModal>
|
||||
`;
|
||||
|
||||
exports[`components/drafts/draft_actions/delete_draft_modal should match snapshot 1`] = `
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`components/drafts/draft_actions/send_draft_modal should have called onConfirm 1`] = `
|
||||
<GenericModal
|
||||
<LegacyGenericModal
|
||||
autoCloseOnCancelButton={true}
|
||||
autoCloseOnConfirmButton={true}
|
||||
bodyPadding={true}
|
||||
@@ -38,11 +38,11 @@ exports[`components/drafts/draft_actions/send_draft_modal should have called onC
|
||||
}
|
||||
}
|
||||
/>
|
||||
</GenericModal>
|
||||
</LegacyGenericModal>
|
||||
`;
|
||||
|
||||
exports[`components/drafts/draft_actions/send_draft_modal should have called onExited 1`] = `
|
||||
<GenericModal
|
||||
<LegacyGenericModal
|
||||
autoCloseOnCancelButton={true}
|
||||
autoCloseOnConfirmButton={true}
|
||||
bodyPadding={true}
|
||||
@@ -79,7 +79,7 @@ exports[`components/drafts/draft_actions/send_draft_modal should have called onE
|
||||
}
|
||||
}
|
||||
/>
|
||||
</GenericModal>
|
||||
</LegacyGenericModal>
|
||||
`;
|
||||
|
||||
exports[`components/drafts/draft_actions/send_draft_modal should match snapshot 1`] = `
|
||||
|
||||
@@ -6,7 +6,7 @@ import React, {useState} from 'react';
|
||||
import {injectIntl, WrappedComponentProps} from 'react-intl';
|
||||
import {useDispatch} from 'react-redux';
|
||||
|
||||
import {GenericModal} from '@mattermost/components';
|
||||
import {LegacyGenericModal} from '@mattermost/components';
|
||||
import {Feedback} from '@mattermost/types/cloud';
|
||||
import {closeModal} from 'actions/views/modals';
|
||||
import RadioButtonGroup from 'components/common/radio_group';
|
||||
@@ -59,7 +59,7 @@ function FeedbackModal(props: Props) {
|
||||
};
|
||||
|
||||
return (
|
||||
<GenericModal
|
||||
<LegacyGenericModal
|
||||
compassDesign={true}
|
||||
onExited={handleCancel}
|
||||
className='FeedbackModal__Container'
|
||||
@@ -102,7 +102,7 @@ function FeedbackModal(props: Props) {
|
||||
</span>
|
||||
</>
|
||||
}
|
||||
</GenericModal>
|
||||
</LegacyGenericModal>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {GenericModal} from '@mattermost/components';
|
||||
import {LegacyGenericModal} from '@mattermost/components';
|
||||
|
||||
import {t} from 'utils/i18n';
|
||||
|
||||
@@ -15,4 +15,4 @@ t('footer_pagination.count');
|
||||
t('footer_pagination.prev');
|
||||
t('footer_pagination.next');
|
||||
|
||||
export default GenericModal;
|
||||
export default LegacyGenericModal;
|
||||
|
||||
@@ -1,96 +0,0 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`components/new_channel_modal should match snapshot 1`] = `
|
||||
<GenericModal
|
||||
autoCloseOnCancelButton={true}
|
||||
autoCloseOnConfirmButton={false}
|
||||
bodyPadding={true}
|
||||
cancelButtonText="Cancel"
|
||||
className="new-channel-modal"
|
||||
compassDesign={true}
|
||||
confirmButtonText="Create channel"
|
||||
enforceFocus={true}
|
||||
errorText=""
|
||||
handleCancel={[Function]}
|
||||
handleConfirm={[Function]}
|
||||
handleEnterKeyPress={[Function]}
|
||||
id="new-channel-modal"
|
||||
isConfirmDisabled={true}
|
||||
keyboardEscape={true}
|
||||
modalHeaderText="Create a new channel"
|
||||
onExited={[Function]}
|
||||
show={true}
|
||||
>
|
||||
<div
|
||||
className="new-channel-modal-body"
|
||||
>
|
||||
<ForwardRef
|
||||
autoComplete="off"
|
||||
autoFocus={true}
|
||||
containerClassName="new-channel-modal-name-container"
|
||||
customMessage={null}
|
||||
inputClassName="new-channel-modal-name-input"
|
||||
label="Channel name"
|
||||
limit={64}
|
||||
name="new-channel-modal-name"
|
||||
onBlur={[Function]}
|
||||
onChange={[Function]}
|
||||
placeholder="Enter a name for your new channel"
|
||||
required={true}
|
||||
type="text"
|
||||
value=""
|
||||
/>
|
||||
<UrlInput
|
||||
base="http://localhost:8065"
|
||||
className="new-channel-modal__url"
|
||||
error=""
|
||||
limit={64}
|
||||
onChange={[Function]}
|
||||
path="current-team/channels"
|
||||
pathInfo=""
|
||||
shortenLength={52}
|
||||
/>
|
||||
<PublicPrivateSelector
|
||||
className="new-channel-modal-type-selector"
|
||||
onChange={[Function]}
|
||||
privateButtonProps={
|
||||
Object {
|
||||
"description": "Only invited members",
|
||||
"disabled": false,
|
||||
"title": "Private Channel",
|
||||
}
|
||||
}
|
||||
publicButtonProps={
|
||||
Object {
|
||||
"description": "Anyone can join",
|
||||
"disabled": false,
|
||||
"title": "Public Channel",
|
||||
}
|
||||
}
|
||||
selected="O"
|
||||
/>
|
||||
<div
|
||||
className="new-channel-modal-purpose-container"
|
||||
>
|
||||
<textarea
|
||||
autoComplete="off"
|
||||
className="new-channel-modal-purpose-textarea"
|
||||
id="new-channel-modal-purpose"
|
||||
maxLength={250}
|
||||
onChange={[Function]}
|
||||
onKeyDown={[Function]}
|
||||
placeholder="Enter a purpose for this channel (optional)"
|
||||
rows={4}
|
||||
value=""
|
||||
/>
|
||||
<div
|
||||
className="new-channel-modal-purpose-info"
|
||||
>
|
||||
<span>
|
||||
This will be displayed when browsing for channels.
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</GenericModal>
|
||||
`;
|
||||
@@ -3,26 +3,19 @@
|
||||
|
||||
import React from 'react';
|
||||
import {act} from 'react-dom/test-utils';
|
||||
import {shallow} from 'enzyme';
|
||||
|
||||
import {mountWithIntl} from 'tests/helpers/intl-test-helper';
|
||||
|
||||
import GenericModal from 'components/generic_modal';
|
||||
import Input from 'components/widgets/inputs/input/input';
|
||||
import URLInput from 'components/widgets/inputs/url_input/url_input';
|
||||
import PublicPrivateSelector from 'components/widgets/public-private-selector/public-private-selector';
|
||||
|
||||
import Constants, {suitePluginIds} from 'utils/constants';
|
||||
import {suitePluginIds} from 'utils/constants';
|
||||
import {cleanUpUrlable} from 'utils/url';
|
||||
import {GlobalState} from 'types/store';
|
||||
import Permissions from 'mattermost-redux/constants/permissions';
|
||||
import {createChannel} from 'mattermost-redux/actions/channels';
|
||||
|
||||
import {ChannelType} from '@mattermost/types/channels';
|
||||
|
||||
jest.mock('mattermost-redux/actions/channels');
|
||||
|
||||
import NewChannelModal from './new_channel_modal';
|
||||
import {render, screen, waitFor} from '@testing-library/react';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
import {renderWithIntl} from 'tests/react_testing_utils';
|
||||
|
||||
const mockDispatch = jest.fn();
|
||||
let mockState: GlobalState;
|
||||
@@ -113,313 +106,324 @@ describe('components/new_channel_modal', () => {
|
||||
} as unknown as GlobalState;
|
||||
});
|
||||
|
||||
test('should match snapshot', () => {
|
||||
expect(
|
||||
shallow(
|
||||
<NewChannelModal/>,
|
||||
),
|
||||
).toMatchSnapshot();
|
||||
test('should match component state with given props', () => {
|
||||
render(<NewChannelModal/>);
|
||||
|
||||
const heading = screen.getByRole('heading');
|
||||
expect(heading).toBeInTheDocument();
|
||||
expect(heading).toHaveAttribute('id', 'genericModalLabel');
|
||||
expect(heading.parentElement).toHaveClass('GenericModal__header');
|
||||
expect(heading).toHaveTextContent('Create a new channel');
|
||||
|
||||
const channelNameHeading = screen.getByText('Channel name');
|
||||
expect(channelNameHeading).toBeInTheDocument();
|
||||
expect(channelNameHeading).toHaveClass('Input_legend Input_legend___focus');
|
||||
|
||||
const channelNameInput = screen.getByPlaceholderText('Enter a name for your new channel');
|
||||
expect(channelNameInput).toBeInTheDocument();
|
||||
expect(channelNameInput).toHaveAttribute('value', '');
|
||||
expect(channelNameInput).toHaveAttribute('type', 'text');
|
||||
expect(channelNameInput).toHaveAttribute('name', 'new-channel-modal-name');
|
||||
expect(channelNameInput).toHaveAttribute('id', 'input_new-channel-modal-name');
|
||||
expect(channelNameInput).toHaveClass('Input form-control medium new-channel-modal-name-input Input__focus');
|
||||
|
||||
const editUrl = screen.getByText('Edit');
|
||||
expect(editUrl).toBeInTheDocument();
|
||||
expect(editUrl).toHaveClass('url-input-button-label');
|
||||
expect(editUrl.parentElement).toHaveClass('url-input-button');
|
||||
|
||||
const publicChannelSvg = screen.getByLabelText('Globe Circle Solid Icon');
|
||||
expect(publicChannelSvg).toBeInTheDocument();
|
||||
|
||||
const publicChannelHeading = screen.getByText('Public Channel');
|
||||
expect(publicChannelHeading).toBeInTheDocument();
|
||||
expect(publicChannelHeading.nextSibling).toHaveTextContent('Anyone can join');
|
||||
|
||||
const privateChannelSvg = screen.getByLabelText('Lock Circle Solid Icon');
|
||||
expect(privateChannelSvg).toBeInTheDocument();
|
||||
|
||||
const privateChannelHeading = screen.getByText('Private Channel');
|
||||
expect(privateChannelHeading).toBeInTheDocument();
|
||||
expect(privateChannelHeading.nextSibling).toHaveTextContent('Only invited members');
|
||||
|
||||
const purposeTextArea = screen.getByPlaceholderText('Enter a purpose for this channel (optional)');
|
||||
expect(purposeTextArea).toBeInTheDocument();
|
||||
expect(purposeTextArea).toHaveClass('new-channel-modal-purpose-textarea');
|
||||
|
||||
const purposeDesc = screen.getByText('This will be displayed when browsing for channels.');
|
||||
expect(purposeDesc).toBeInTheDocument();
|
||||
|
||||
const cancelButton = screen.getByText('Cancel');
|
||||
expect(cancelButton).toBeInTheDocument();
|
||||
expect(cancelButton).toHaveClass('GenericModal__button cancel');
|
||||
|
||||
const createChannelButton = screen.getByText('Create channel');
|
||||
expect(createChannelButton).toBeInTheDocument();
|
||||
expect(createChannelButton).toHaveClass('GenericModal__button confirm');
|
||||
expect(createChannelButton).toBeDisabled();
|
||||
});
|
||||
|
||||
test('should handle display name change', () => {
|
||||
const value = 'Channel name';
|
||||
const mockChangeEvent = {
|
||||
preventDefault: jest.fn(),
|
||||
target: {
|
||||
value,
|
||||
},
|
||||
} as unknown as React.ChangeEvent<HTMLInputElement>;
|
||||
|
||||
const wrapper = shallow(
|
||||
render(
|
||||
<NewChannelModal/>,
|
||||
);
|
||||
|
||||
// Change display name
|
||||
let input = wrapper.find(Input).first();
|
||||
input.props().onChange!(mockChangeEvent);
|
||||
const channelNameInput = screen.getByPlaceholderText('Enter a name for your new channel');
|
||||
expect(channelNameInput).toBeInTheDocument();
|
||||
expect(channelNameInput).toHaveAttribute('value', '');
|
||||
|
||||
userEvent.type(channelNameInput, value);
|
||||
|
||||
// Display name should have been updated
|
||||
input = wrapper.find(Input).first();
|
||||
expect(input.props().value).toEqual(value);
|
||||
expect(channelNameInput).toHaveAttribute('value', value);
|
||||
|
||||
// URL should have been changed according to display name
|
||||
const urlInput = wrapper.find(URLInput);
|
||||
expect(urlInput.props().pathInfo).toEqual(cleanUpUrlable(value));
|
||||
const urlInputLabel = screen.getByTestId('urlInputLabel');
|
||||
expect(urlInputLabel).toHaveTextContent(cleanUpUrlable(value));
|
||||
});
|
||||
|
||||
test('should handle url change', () => {
|
||||
test('should handle url change', async () => {
|
||||
const value = 'Channel name';
|
||||
const mockInputChangeEvent = {
|
||||
preventDefault: jest.fn(),
|
||||
target: {
|
||||
value,
|
||||
},
|
||||
} as unknown as React.ChangeEvent<HTMLInputElement>;
|
||||
const mockInputChangeUpdatedEvent = {
|
||||
preventDefault: jest.fn(),
|
||||
target: {
|
||||
value: `${value} updated`,
|
||||
},
|
||||
} as unknown as React.ChangeEvent<HTMLInputElement>;
|
||||
|
||||
const url = 'channel-name-new';
|
||||
const mockURLInputChangeEvent = {
|
||||
preventDefault: jest.fn(),
|
||||
target: {
|
||||
value: url,
|
||||
},
|
||||
} as unknown as React.ChangeEvent<HTMLInputElement>;
|
||||
|
||||
const wrapper = shallow(
|
||||
render(
|
||||
<NewChannelModal/>,
|
||||
);
|
||||
|
||||
// Change display name
|
||||
let input = wrapper.find(Input).first();
|
||||
input.props().onChange!(mockInputChangeEvent);
|
||||
const channelNameInput = screen.getByPlaceholderText('Enter a name for your new channel');
|
||||
expect(channelNameInput).toBeInTheDocument();
|
||||
expect(channelNameInput).toHaveAttribute('value', '');
|
||||
|
||||
// URL should have been changed according to display name
|
||||
let urlInput = wrapper.find(URLInput);
|
||||
expect(urlInput.props().pathInfo).toEqual(cleanUpUrlable(value));
|
||||
userEvent.type(channelNameInput, value);
|
||||
const urlInputLabel = screen.getByTestId('urlInputLabel');
|
||||
expect(urlInputLabel).toHaveTextContent(cleanUpUrlable(value));
|
||||
|
||||
// Change URL
|
||||
urlInput.props().onChange!(mockURLInputChangeEvent);
|
||||
const editUrl = screen.getByText('Edit');
|
||||
expect(editUrl).toBeInTheDocument();
|
||||
|
||||
userEvent.click(editUrl);
|
||||
|
||||
const editUrlInput = screen.getByTestId('channelURLInput');
|
||||
userEvent.clear(editUrlInput);
|
||||
userEvent.type(editUrlInput, url);
|
||||
|
||||
const doneButton = screen.getByText('Done');
|
||||
await waitFor(() =>
|
||||
userEvent.click(doneButton),
|
||||
);
|
||||
|
||||
// URL should have been updated
|
||||
urlInput = wrapper.find(URLInput);
|
||||
expect(urlInput.props().pathInfo).toEqual(url);
|
||||
expect(screen.getByText(url, {exact: false})).toBeInTheDocument();
|
||||
|
||||
// Change display name again
|
||||
input = wrapper.find(Input).first();
|
||||
input.props().onChange!(mockInputChangeUpdatedEvent);
|
||||
userEvent.type(channelNameInput, `${value} updated`);
|
||||
|
||||
// URL should NOT be updated
|
||||
urlInput = wrapper.find(URLInput);
|
||||
expect(urlInput.props().pathInfo).toEqual(url);
|
||||
expect(screen.getByText(url, {exact: false})).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test('should handle type changes', () => {
|
||||
const typePublic = Constants.OPEN_CHANNEL as ChannelType;
|
||||
const typePrivate = Constants.PRIVATE_CHANNEL as ChannelType;
|
||||
|
||||
const wrapper = shallow(
|
||||
render(
|
||||
<NewChannelModal/>,
|
||||
);
|
||||
|
||||
// Change type to private
|
||||
let selector = wrapper.find(PublicPrivateSelector);
|
||||
selector.props().onChange!(typePrivate);
|
||||
const privateChannel = screen.getByText('Private Channel');
|
||||
expect(privateChannel).toBeInTheDocument();
|
||||
|
||||
userEvent.click(privateChannel);
|
||||
|
||||
// Type should have been updated to private
|
||||
selector = wrapper.find(PublicPrivateSelector);
|
||||
expect(selector.props().selected).toEqual(typePrivate);
|
||||
expect(privateChannel.parentElement?.nextSibling?.firstChild).toHaveAttribute('aria-label', 'Check Circle Icon');
|
||||
|
||||
// Change type to private
|
||||
selector = wrapper.find(PublicPrivateSelector);
|
||||
selector.props().onChange!(typePublic);
|
||||
// Change type to public
|
||||
const publicChannel = screen.getByText('Public Channel');
|
||||
expect(publicChannel).toBeInTheDocument();
|
||||
|
||||
userEvent.click(publicChannel);
|
||||
|
||||
// Type should have been updated to public
|
||||
selector = wrapper.find(PublicPrivateSelector);
|
||||
expect(selector.props().selected).toEqual(typePublic);
|
||||
expect(publicChannel.parentElement?.nextSibling?.firstChild).toHaveAttribute('aria-label', 'Check Circle Icon');
|
||||
});
|
||||
|
||||
test('should handle purpose changes', () => {
|
||||
const value = 'Purpose';
|
||||
const mockChangeEvent = {
|
||||
preventDefault: jest.fn(),
|
||||
target: {
|
||||
value,
|
||||
},
|
||||
} as unknown as React.ChangeEvent<HTMLTextAreaElement>;
|
||||
|
||||
const wrapper = shallow(
|
||||
render(
|
||||
<NewChannelModal/>,
|
||||
);
|
||||
|
||||
// Change purpose
|
||||
let textarea = wrapper.find('textarea');
|
||||
textarea.props().onChange!(mockChangeEvent);
|
||||
const ChannelPurposeTextArea = screen.getByPlaceholderText('Enter a purpose for this channel (optional)');
|
||||
expect(ChannelPurposeTextArea).toBeInTheDocument();
|
||||
|
||||
userEvent.click(ChannelPurposeTextArea);
|
||||
userEvent.type(ChannelPurposeTextArea, value);
|
||||
|
||||
// Purpose should have been updated
|
||||
textarea = wrapper.find('textarea');
|
||||
expect(textarea.props().value).toEqual(value);
|
||||
expect(ChannelPurposeTextArea).toHaveValue(value);
|
||||
});
|
||||
|
||||
test('should enable confirm button when having valid display name, url and type', () => {
|
||||
const mockChangeEvent = {
|
||||
preventDefault: jest.fn(),
|
||||
target: {
|
||||
value: 'Channel name',
|
||||
},
|
||||
} as unknown as React.ChangeEvent<HTMLInputElement>;
|
||||
|
||||
const wrapper = shallow(
|
||||
render(
|
||||
<NewChannelModal/>,
|
||||
);
|
||||
|
||||
// Confirm button should be disabled
|
||||
let genericModal = wrapper.find(GenericModal);
|
||||
expect(genericModal.props().isConfirmDisabled).toEqual(true);
|
||||
const createChannelButton = screen.getByText('Create channel');
|
||||
expect(createChannelButton).toBeInTheDocument();
|
||||
expect(createChannelButton).toBeDisabled();
|
||||
|
||||
// Change display name
|
||||
const input = wrapper.find(Input).first();
|
||||
input.props().onChange!(mockChangeEvent);
|
||||
const channelNameInput = screen.getByPlaceholderText('Enter a name for your new channel');
|
||||
expect(channelNameInput).toBeInTheDocument();
|
||||
expect(channelNameInput).toHaveAttribute('value', '');
|
||||
|
||||
userEvent.type(channelNameInput, 'Channel name');
|
||||
|
||||
// Change type to private
|
||||
const selector = wrapper.find(PublicPrivateSelector);
|
||||
selector.props().onChange!(Constants.PRIVATE_CHANNEL as ChannelType);
|
||||
const privateChannel = screen.getByText('Private Channel');
|
||||
expect(privateChannel).toBeInTheDocument();
|
||||
|
||||
userEvent.click(privateChannel);
|
||||
|
||||
// Confirm button should be enabled
|
||||
genericModal = wrapper.find(GenericModal);
|
||||
expect(genericModal.props().isConfirmDisabled).toEqual(false);
|
||||
expect(createChannelButton).toBeEnabled();
|
||||
});
|
||||
|
||||
test('should disable confirm button when display name in error', () => {
|
||||
const mockChangeEvent = {
|
||||
preventDefault: jest.fn(),
|
||||
target: {
|
||||
value: 'Channel name',
|
||||
},
|
||||
} as unknown as React.ChangeEvent<HTMLInputElement>;
|
||||
const mockChangeInvalidEvent = {
|
||||
preventDefault: jest.fn(),
|
||||
target: {
|
||||
value: '',
|
||||
},
|
||||
} as unknown as React.ChangeEvent<HTMLInputElement>;
|
||||
|
||||
const wrapper = shallow(
|
||||
render(
|
||||
<NewChannelModal/>,
|
||||
);
|
||||
|
||||
// Change display name
|
||||
let input = wrapper.find(Input).first();
|
||||
input.props().onChange!(mockChangeEvent);
|
||||
const channelNameInput = screen.getByPlaceholderText('Enter a name for your new channel');
|
||||
expect(channelNameInput).toBeInTheDocument();
|
||||
expect(channelNameInput).toHaveAttribute('value', '');
|
||||
|
||||
userEvent.type(channelNameInput, 'Channel name');
|
||||
|
||||
// Change type to private
|
||||
const selector = wrapper.find(PublicPrivateSelector);
|
||||
selector.props().onChange!(Constants.PRIVATE_CHANNEL as ChannelType);
|
||||
const privateChannel = screen.getByText('Private Channel');
|
||||
expect(privateChannel).toBeInTheDocument();
|
||||
|
||||
userEvent.click(privateChannel);
|
||||
|
||||
// Confirm button should be enabled
|
||||
let genericModal = wrapper.find(GenericModal);
|
||||
expect(genericModal.props().isConfirmDisabled).toEqual(false);
|
||||
const createChannelButton = screen.getByText('Create channel');
|
||||
expect(createChannelButton).toBeEnabled();
|
||||
|
||||
// Change display name to invalid
|
||||
input = wrapper.find(Input).first();
|
||||
input.props().onChange!(mockChangeInvalidEvent);
|
||||
userEvent.clear(channelNameInput);
|
||||
userEvent.type(channelNameInput, '');
|
||||
|
||||
// Confirm button should be disabled
|
||||
genericModal = wrapper.find(GenericModal);
|
||||
expect(genericModal.props().isConfirmDisabled).toEqual(true);
|
||||
expect(createChannelButton).toBeDisabled();
|
||||
});
|
||||
|
||||
test('should disable confirm button when url in error', () => {
|
||||
const mockChangeEvent = {
|
||||
preventDefault: jest.fn(),
|
||||
target: {
|
||||
value: 'Channel name',
|
||||
},
|
||||
} as unknown as React.ChangeEvent<HTMLInputElement>;
|
||||
const mockChangeURLInvalidEvent = {
|
||||
preventDefault: jest.fn(),
|
||||
target: {
|
||||
value: 'c-',
|
||||
},
|
||||
} as unknown as React.ChangeEvent<HTMLInputElement>;
|
||||
|
||||
const wrapper = shallow(
|
||||
render(
|
||||
<NewChannelModal/>,
|
||||
);
|
||||
|
||||
// Change display name
|
||||
const input = wrapper.find(Input).first();
|
||||
input.props().onChange!(mockChangeEvent);
|
||||
const channelNameInput = screen.getByPlaceholderText('Enter a name for your new channel');
|
||||
expect(channelNameInput).toBeInTheDocument();
|
||||
expect(channelNameInput).toHaveAttribute('value', '');
|
||||
|
||||
userEvent.type(channelNameInput, 'Channel name');
|
||||
|
||||
// Change type to private
|
||||
const selector = wrapper.find(PublicPrivateSelector);
|
||||
selector.props().onChange!(Constants.PRIVATE_CHANNEL as ChannelType);
|
||||
const privateChannel = screen.getByText('Private Channel');
|
||||
expect(privateChannel).toBeInTheDocument();
|
||||
|
||||
userEvent.click(privateChannel);
|
||||
|
||||
// Confirm button should be enabled
|
||||
let genericModal = wrapper.find(GenericModal);
|
||||
expect(genericModal.props().isConfirmDisabled).toEqual(false);
|
||||
const createChannelButton = screen.getByText('Create channel');
|
||||
expect(createChannelButton).toBeEnabled();
|
||||
|
||||
// Change url to invalid
|
||||
const urlInput = wrapper.find(URLInput);
|
||||
urlInput.props().onChange!(mockChangeURLInvalidEvent);
|
||||
const editUrl = screen.getByText('Edit');
|
||||
expect(editUrl).toBeInTheDocument();
|
||||
|
||||
userEvent.click(editUrl);
|
||||
|
||||
const editUrlInput = screen.getByTestId('channelURLInput');
|
||||
userEvent.clear(editUrlInput);
|
||||
userEvent.type(editUrlInput, 'c-');
|
||||
|
||||
// Confirm button should be disabled
|
||||
genericModal = wrapper.find(GenericModal);
|
||||
expect(genericModal.props().isConfirmDisabled).toEqual(true);
|
||||
expect(createChannelButton).toBeDisabled();
|
||||
});
|
||||
|
||||
test('should disable confirm button when server error', async () => {
|
||||
const mockChangeEvent = {
|
||||
preventDefault: jest.fn(),
|
||||
target: {
|
||||
value: 'Channel name',
|
||||
},
|
||||
} as unknown as React.ChangeEvent<HTMLInputElement>;
|
||||
|
||||
const wrapper = shallow(
|
||||
render(
|
||||
<NewChannelModal/>,
|
||||
);
|
||||
|
||||
// Confirm button should be disabled
|
||||
let genericModal = wrapper.find(GenericModal);
|
||||
expect(genericModal.props().isConfirmDisabled).toEqual(true);
|
||||
const createChannelButton = screen.getByText('Create channel');
|
||||
expect(createChannelButton).toBeDisabled();
|
||||
|
||||
// Change display name
|
||||
const input = wrapper.find(Input).first();
|
||||
input.props().onChange!(mockChangeEvent);
|
||||
const channelNameInput = screen.getByPlaceholderText('Enter a name for your new channel');
|
||||
expect(channelNameInput).toBeInTheDocument();
|
||||
expect(channelNameInput).toHaveAttribute('value', '');
|
||||
|
||||
userEvent.type(channelNameInput, 'Channel name');
|
||||
|
||||
// Change type to private
|
||||
const selector = wrapper.find(PublicPrivateSelector);
|
||||
selector.props().onChange!(Constants.PRIVATE_CHANNEL as ChannelType);
|
||||
const privateChannel = screen.getByText('Private Channel');
|
||||
expect(privateChannel).toBeInTheDocument();
|
||||
|
||||
userEvent.click(privateChannel);
|
||||
|
||||
// Confirm button should be enabled
|
||||
genericModal = wrapper.find(GenericModal);
|
||||
expect(genericModal.props().isConfirmDisabled).toEqual(false);
|
||||
expect(createChannelButton).toBeEnabled();
|
||||
|
||||
// Submit
|
||||
await genericModal.props().handleConfirm!();
|
||||
await act(async () => userEvent.click(createChannelButton));
|
||||
|
||||
genericModal = wrapper.find(GenericModal);
|
||||
expect(genericModal.props().errorText).toEqual('Something went wrong. Please try again.');
|
||||
expect(genericModal.props().isConfirmDisabled).toEqual(true);
|
||||
const serverError = screen.getByText('Something went wrong. Please try again.');
|
||||
expect(serverError).toBeInTheDocument();
|
||||
expect(createChannelButton).toBeDisabled();
|
||||
});
|
||||
|
||||
test('should request team creation on submit', async () => {
|
||||
const name = 'Channel name';
|
||||
const mockChangeEvent = {
|
||||
preventDefault: jest.fn(),
|
||||
target: {
|
||||
value: name,
|
||||
},
|
||||
} as unknown as React.ChangeEvent<HTMLInputElement>;
|
||||
|
||||
const wrapper = mountWithIntl(
|
||||
renderWithIntl(
|
||||
<NewChannelModal/>,
|
||||
);
|
||||
|
||||
const genericModal = wrapper.find('GenericModal');
|
||||
const displayName = genericModal.find('.new-channel-modal-name-input');
|
||||
const confirmButton = genericModal.find('button[type=\'submit\']');
|
||||
|
||||
// Confirm button should be disabled
|
||||
expect((confirmButton.instance() as unknown as HTMLButtonElement).disabled).toEqual(true);
|
||||
const createChannelButton = screen.getByText('Create channel');
|
||||
expect(createChannelButton).toBeDisabled();
|
||||
|
||||
// Enter data
|
||||
displayName.simulate('change', mockChangeEvent);
|
||||
|
||||
const channelNameInput = screen.getByPlaceholderText('Enter a name for your new channel');
|
||||
expect(channelNameInput).toBeInTheDocument();
|
||||
expect(channelNameInput).toHaveAttribute('value', '');
|
||||
|
||||
userEvent.type(channelNameInput, name);
|
||||
|
||||
// Display name should be updated
|
||||
expect((displayName.instance() as unknown as HTMLInputElement).value).toEqual(name);
|
||||
expect(channelNameInput).toHaveValue(name);
|
||||
|
||||
// Confirm button should be enabled
|
||||
expect((confirmButton.instance() as unknown as HTMLButtonElement).disabled).toEqual(false);
|
||||
expect(createChannelButton).toBeEnabled();
|
||||
|
||||
// Submit
|
||||
await act(async () => {
|
||||
confirmButton.simulate('click');
|
||||
userEvent.click(createChannelButton);
|
||||
});
|
||||
|
||||
// Request should be sent
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`ProductNoticesModal Match snapshot for single notice 1`] = `
|
||||
<GenericModal
|
||||
<LegacyGenericModal
|
||||
autoCloseOnCancelButton={false}
|
||||
autoCloseOnConfirmButton={true}
|
||||
bodyPadding={true}
|
||||
@@ -38,11 +38,11 @@ exports[`ProductNoticesModal Match snapshot for single notice 1`] = `
|
||||
<div
|
||||
className="productNotices__info"
|
||||
/>
|
||||
</GenericModal>
|
||||
</LegacyGenericModal>
|
||||
`;
|
||||
|
||||
exports[`ProductNoticesModal Match snapshot for user notice 1`] = `
|
||||
<GenericModal
|
||||
<LegacyGenericModal
|
||||
autoCloseOnCancelButton={false}
|
||||
autoCloseOnConfirmButton={true}
|
||||
bodyPadding={true}
|
||||
@@ -117,11 +117,11 @@ exports[`ProductNoticesModal Match snapshot for user notice 1`] = `
|
||||
/>
|
||||
</span>
|
||||
</div>
|
||||
</GenericModal>
|
||||
</LegacyGenericModal>
|
||||
`;
|
||||
|
||||
exports[`ProductNoticesModal Should match snapshot for system admin notice 1`] = `
|
||||
<GenericModal
|
||||
<LegacyGenericModal
|
||||
autoCloseOnCancelButton={false}
|
||||
autoCloseOnConfirmButton={false}
|
||||
bodyPadding={true}
|
||||
@@ -200,7 +200,7 @@ exports[`ProductNoticesModal Should match snapshot for system admin notice 1`] =
|
||||
id="inProduct_notices.adminOnlyMessage"
|
||||
/>
|
||||
</div>
|
||||
</GenericModal>
|
||||
</LegacyGenericModal>
|
||||
`;
|
||||
|
||||
exports[`ProductNoticesModal Should match snapshot when there are no notices 1`] = `""`;
|
||||
|
||||
@@ -5,7 +5,7 @@ import React from 'react';
|
||||
import {useSelector} from 'react-redux';
|
||||
import {FormattedMessage} from 'react-intl';
|
||||
|
||||
import {GenericModal, GenericModalProps} from '@mattermost/components';
|
||||
import {LegacyGenericModal, LegacyGenericModalProps} from '@mattermost/components';
|
||||
|
||||
import {getCurrentUser} from 'mattermost-redux/selectors/entities/common';
|
||||
import {getUserByEmail} from 'mattermost-redux/selectors/entities/users';
|
||||
@@ -48,7 +48,7 @@ export default function PurchaseInProgressModal(props: Props) {
|
||||
/>
|
||||
);
|
||||
let actionToTake;
|
||||
const genericModalProps: Partial<GenericModalProps> = {};
|
||||
const genericModalProps: Partial<LegacyGenericModalProps> = {};
|
||||
if (sameUserAlreadyPurchasing) {
|
||||
description = (
|
||||
<FormattedMessage
|
||||
@@ -76,7 +76,7 @@ export default function PurchaseInProgressModal(props: Props) {
|
||||
);
|
||||
}
|
||||
return (
|
||||
<GenericModal
|
||||
<LegacyGenericModal
|
||||
onExited={close}
|
||||
show={true}
|
||||
modalHeaderText={header}
|
||||
@@ -98,6 +98,6 @@ export default function PurchaseInProgressModal(props: Props) {
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</GenericModal>
|
||||
</LegacyGenericModal>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
import React from 'react';
|
||||
import {FormattedMessage} from 'react-intl';
|
||||
|
||||
import {GenericModal} from '@mattermost/components';
|
||||
import {LegacyGenericModal} from '@mattermost/components';
|
||||
import AccessDeniedHappySvg from 'components/common/svg_images_components/access_denied_happy_svg';
|
||||
import {useControlScreeningInProgressModal} from 'components/common/hooks/useControlModal';
|
||||
|
||||
@@ -14,7 +14,7 @@ export default function ScreeningInProgressModal() {
|
||||
const {close} = useControlScreeningInProgressModal();
|
||||
|
||||
return (
|
||||
<GenericModal
|
||||
<LegacyGenericModal
|
||||
onExited={close}
|
||||
show={true}
|
||||
className='ScreeningInProgressModal'
|
||||
@@ -49,6 +49,6 @@ export default function ScreeningInProgressModal() {
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</GenericModal>
|
||||
</LegacyGenericModal>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
import * as React from 'react';
|
||||
import {useIntl} from 'react-intl';
|
||||
|
||||
import {GenericModal} from '@mattermost/components';
|
||||
import {LegacyGenericModal} from '@mattermost/components';
|
||||
|
||||
import './mark_all_threads_as_read_modal.scss';
|
||||
|
||||
@@ -20,7 +20,7 @@ function MarkAllThreadsAsReadModal({
|
||||
const {formatMessage} = useIntl();
|
||||
|
||||
return (
|
||||
<GenericModal
|
||||
<LegacyGenericModal
|
||||
className='mark-all-threads-as-read'
|
||||
id='mark-all-threads-as-read-modal'
|
||||
compassDesign={true}
|
||||
@@ -48,7 +48,7 @@ function MarkAllThreadsAsReadModal({
|
||||
})}
|
||||
</span>
|
||||
</div>
|
||||
</GenericModal>
|
||||
</LegacyGenericModal>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -79,7 +79,10 @@ function UrlInput({
|
||||
};
|
||||
|
||||
const urlInputLabel = (
|
||||
<span className='url-input-label'>
|
||||
<span
|
||||
className='url-input-label'
|
||||
data-testid='urlInputLabel'
|
||||
>
|
||||
{formatMessage({id: 'url_input.label.url', defaultMessage: 'URL: '})}
|
||||
{isShortenedURL ? getShortenedURL(fullURL, shortenLength) : fullURL}
|
||||
</span>
|
||||
@@ -105,6 +108,7 @@ function UrlInput({
|
||||
)}
|
||||
{(editing || hasError) && (
|
||||
<Input
|
||||
data-testid='channelURLInput'
|
||||
name='url-input'
|
||||
type='text'
|
||||
containerClassName='url-input-editable-container'
|
||||
|
||||
Ссылка в новой задаче
Block a user