Skip to content

Commit

Permalink
[MM-61647][MM-61651]: Upgraded react-select to v5 (mattermost#30070)
Browse files Browse the repository at this point in the history
* [MM-61647]: Upgraded react-select to v5
- Updated old type definitions with new v5 packaged type definitions.
- Removed some unused props
- Updated onBlur, onFocus and handleInputChange methods in user_input_email component

* Fix incorrect usage of handleInputChange in ChannelsInput

* Remove type assertions from dropdown_input_hybrid.tsx

* Simplify typing of users_emails_input.tsx

* [MM-61647][MM-61651]: Fixed some type definitions and e2e failing test case

* [MM-61647][MM-61651]: Fixed type error in dropdown_input_hybrid

* [MM-61647][MM-61651]: Fixed failing CI type error and e2e test cases

* [MM-61647][MM-61651]: Fixed failing e2e test case

* [MM-61647][MM-61651]: Updated the styles and reverted the test case changes
- Fixed the theme not getting correctly inherited
- Fixed the timezone and language settings getting saved on enter

---------

Co-authored-by: Harrison Healey <harrisonmhealey@gmail.com>
Co-authored-by: Mattermost Build <build@mattermost.com>
  • Loading branch information
3 people authored Feb 25, 2025
1 parent 6ecaad2 commit 8e9a09e
Show file tree
Hide file tree
Showing 64 changed files with 783 additions and 620 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -169,36 +169,43 @@ describe('Verify Accessibility Support in different sections in Settings and Pro

cy.get('#displayButton').click();
cy.get('#languagesEdit').click();
cy.get('#displayLanguage').within(() => {
cy.get('input').should('have.attr', 'aria-autocomplete', 'list').and('have.attr', 'aria-labelledby', 'changeInterfaceLanguageLabel').as('inputEl');
});
cy.findByRole('combobox', {name: 'Dropdown selector to change the interface language'}).should('have.attr', 'aria-autocomplete', 'list').and('have.attr', 'aria-labelledby', 'changeInterfaceLanguageLabel').as('inputEl');
cy.get('#changeInterfaceLanguageLabel').should('be.visible').and('have.text', 'Change interface language');

// # When enter key is pressed on dropdown, it should expand and collapse
cy.get('@inputEl').typeWithForce('{enter}');
cy.get('#displayLanguage>div').should('have.class', 'react-select__control--menu-is-open');
cy.get('@inputEl').typeWithForce('{enter}');
cy.get('#displayLanguage>div').should('not.have.class', 'react-select__control--menu-is-open');
// # When space key is pressed on dropdown, it should expand and should collapse when esc key is pressed
cy.get('@inputEl').typeWithForce(' ');
cy.findByRole('listbox').should('have.class', 'react-select__menu-list').as('listBox');
cy.get('@inputEl').typeWithForce('{esc}');
cy.get('@listBox').should('not.exist');

// # Press down arrow twice and check aria label
cy.get('@inputEl').typeWithForce('{enter}');
cy.get('@inputEl').typeWithForce(' ');
cy.get('@inputEl').typeWithForce('{downarrow}{downarrow}');
cy.get('#displayLanguage>span').as('ariaEl').within(($el) => {
cy.wrap($el).should('have.attr', 'aria-live', 'assertive');
cy.get('#aria-context').should('contain', 'option English (Australia) focused').and('contain', 'Use Up and Down to choose options, press Enter to select the currently focused option, press Escape to exit the menu, press Tab to select the option and exit the menu.');
cy.get('#displayLanguage').within(($el) => {
cy.wrap($el).findByRole('log').should('have.attr', 'aria-live', 'assertive').as('ariaEl');
});
cy.get('@ariaEl').within(($el) => {
cy.wrap($el).get('#aria-focused').should('contain', 'option English (Australia) focused');
cy.wrap($el).get('#aria-guidance').should('contain', 'Use Up and Down to choose options, press Enter to select the currently focused option, press Escape to exit the menu, press Tab to select the option and exit the menu.');
});

// # Check if language setting gets changed after user presses enter
cy.get('@inputEl').typeWithForce('{enter}');
// # Check if language setting gets changed after user presses space
cy.get('@inputEl').typeWithForce(' ');
cy.get('#displayLanguage').should('contain', 'English (Australia)');
cy.get('@ariaEl').get('#aria-selection-event').should('contain', 'option English (Australia), selected');
cy.get('@ariaEl').within(($el) => {
cy.wrap($el).get('#aria-selection').should('contain', 'option English (Australia) selected');
});

// # Press down arrow, then up arrow and press enter
// # Press down arrow, then up arrow and press space
cy.get('@inputEl').typeWithForce('{downarrow}{downarrow}{downarrow}{uparrow}');
cy.get('@ariaEl').get('#aria-context').should('contain', 'option English (US) focused');
cy.get('@inputEl').typeWithForce('{enter}');
cy.get('@ariaEl').within(($el) => {
cy.wrap($el).get('#aria-focused').should('contain', 'option English (US) focused');
});
cy.get('@inputEl').typeWithForce(' ');
cy.get('#displayLanguage').should('contain', 'English (US)');
cy.get('@ariaEl').get('#aria-selection-event').should('contain', 'option English (US), selected');
cy.get('@ariaEl').within(($el) => {
cy.wrap($el).get('#aria-selection').should('contain', 'option English (US) selected');
});
});

it('MM-T1488 Profile Picture should read labels', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ describe('Group Message Conversion To Private Channel', () => {
cy.get('.GenericModal__button.delete.disabled').wait(2000);

// Open the team dropdown and select a team
cy.findByText('Select Team').click();
cy.findByText('Select Team').click({force: true});
cy.findByText(testTeam2.display_name).click();

// Enter the new channel name and confirm
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ describe('Verify Guest User Identification in different screens', () => {
// # Open a DM with Guest User
cy.uiAddDirectMessage().click();
cy.findByRole('dialog', {name: 'Direct Messages'}).should('be.visible').wait(TIMEOUTS.ONE_SEC);
cy.findByRole('textbox', {name: 'Search for people'}).
cy.findByRole('combobox', {name: 'Search for people'}).
should('have.focused').
typeWithForce(guestUser.username).
wait(TIMEOUTS.ONE_SEC).
Expand All @@ -182,12 +182,12 @@ describe('Verify Guest User Identification in different screens', () => {
// # Open a GM with Guest User and Sysadmin
cy.uiAddDirectMessage().click();
cy.findByRole('dialog', {name: 'Direct Messages'}).should('be.visible').wait(TIMEOUTS.ONE_SEC);
cy.findByRole('textbox', {name: 'Search for people'}).
cy.findByRole('combobox', {name: 'Search for people'}).
should('have.focused').
typeWithForce(guestUser.username).
wait(TIMEOUTS.ONE_SEC).
typeWithForce('{enter}');
cy.findByRole('textbox', {name: 'Search for people'}).
cy.findByRole('combobox', {name: 'Search for people'}).
should('have.focused').
typeWithForce(admin.username).
wait(TIMEOUTS.ONE_SEC).
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ describe('Channel members test', () => {
cy.get('#addChannelMembers').click();

// # Enter user1 and user2 emails
cy.findByRole('textbox', {name: 'Search for people or groups'}).typeWithForce(`${user1.email}{enter}${user2.email}{enter}`);
cy.findByRole('combobox', {name: 'Search for people or groups'}).typeWithForce(`${user1.email}{enter}${user2.email}{enter}`);

// # Confirm add the users
cy.get('#addUsersToChannelModal #saveItems').click();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ export function makeUserASystemRole(testUsers, role) {
cy.findByRole('button', {name: 'Add People'}).click().wait(TIMEOUTS.HALF_SEC);

// # Type in user name
cy.findByRole('textbox', {name: 'Search for people'}).typeWithForce(`${testUsers[role].email}`);
cy.findByRole('combobox', {name: 'Search for people'}).typeWithForce(`${testUsers[role].email}`);

// # Find the user and click on him
cy.get('#multiSelectList').should('be.visible').children().first().click({force: true});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ describe('User Management', () => {
cy.findByRole('button', {name: 'Add People'}).click().wait(TIMEOUTS.HALF_SEC);

// # Type in user name
cy.findByRole('textbox', {name: 'Search for people'}).typeWithForce(`${userEmail}`);
cy.findByRole('combobox', {name: 'Search for people'}).typeWithForce(`${userEmail}`);

// # Find the user and click on him
cy.get('#multiSelectList').should('be.visible').children().first().click({force: true});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ describe('Messaging', () => {

// # Search for the deactivated user
cy.findByRole('dialog', {name: 'Direct Messages'}).should('be.visible').wait(TIMEOUTS.ONE_SEC);
cy.findByRole('textbox', {name: 'Search for people'}).typeWithForce(deactivatedUser.email);
cy.findByRole('combobox', {name: 'Search for people'}).typeWithForce(deactivatedUser.email);

// * Verify that the inactive user is not found
cy.get('.no-channel-message').should('be.visible').and('contain', 'No results found matching');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ describe('Header', () => {
// # Open a DM with the bot
cy.uiAddDirectMessage().click().wait(TIMEOUTS.ONE_SEC);
cy.findByRole('dialog', {name: 'Direct Messages'}).should('be.visible').wait(TIMEOUTS.ONE_SEC);
cy.findByRole('textbox', {name: 'Search for people'}).
cy.findByRole('combobox', {name: 'Search for people'}).
typeWithForce('matterpoll').wait(TIMEOUTS.ONE_SEC).
typeWithForce('{enter}');
cy.get('#selectItems').contains('matterpoll');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ describe('Multi Team and DM', () => {
cy.findByText('Previous').should('exist');

// # Enter a search term
cy.findByRole('textbox', {name: 'Search for people'}).typeWithForce(searchTerm);
cy.findByRole('combobox', {name: 'Search for people'}).typeWithForce(searchTerm);

// * Assert that the previous / next links do not appear since there should only be 1 record displayed
cy.findByText('Next').should('not.exist');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ describe('Multi Team and DM', () => {
const totalUsers = number.text().split(' ').slice(2, 3);

// * Assert that 2 unique users are displayed
cy.findByRole('textbox', {name: 'Search for people'}).typeWithForce(unique).then(() => {
cy.findByRole('combobox', {name: 'Search for people'}).typeWithForce(unique).then(() => {
cy.get('#multiSelectList').within(() => {
cy.get('.more-modal__details').should('have.length', 2);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ describe('Multi-user group messages', () => {
cy.findByRole('dialog', {name: 'Direct Messages'}).should('be.visible').wait(TIMEOUTS.ONE_SEC);

// # Start typing part of a username that matches previously created users
cy.findByRole('textbox', {name: 'Search for people'}).
cy.findByRole('combobox', {name: 'Search for people'}).
typeWithForce(searchTerm).
wait(TIMEOUTS.ONE_SEC);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ describe('System Console > User Management > Deactivation', () => {
cy.findByRole('dialog', {name: 'Direct Messages'}).should('be.visible').wait(TIMEOUTS.ONE_SEC);

// # Start typing part of a username that matches previously created users
cy.findByRole('textbox', {name: 'Search for people'}).
cy.findByRole('combobox', {name: 'Search for people'}).
typeWithForce(other.username).
wait(TIMEOUTS.ONE_SEC);

Expand Down Expand Up @@ -127,7 +127,7 @@ describe('System Console > User Management > Deactivation', () => {
cy.uiAddDirectMessage().click().wait(TIMEOUTS.HALF_SEC);

// # Type the user name of user1 on Channel switcher input
cy.findByRole('textbox', {name: 'Search for people'}).
cy.findByRole('combobox', {name: 'Search for people'}).
typeWithForce(user1.username).
wait(TIMEOUTS.ONE_SEC);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ describe('Team Settings', () => {
cy.get('.InviteAs').findByTestId('inviteMembersLink').click();
}

cy.findByRole('textbox', {name: 'Add or Invite People'}).type(email, {force: true}).wait(TIMEOUTS.HALF_SEC).type('{enter}', {force: true});
cy.findByRole('combobox', {name: 'Add or Invite People'}).type(email, {force: true}).wait(TIMEOUTS.HALF_SEC).type('{enter}', {force: true});
cy.findByTestId('inviteButton').click();

// # Wait for a while to ensure that email notification is sent and logout from sysadmin account
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ describe('Team Settings', () => {
function inviteNewMemberToTeam(email) {
cy.wait(TIMEOUTS.HALF_SEC);

cy.findByRole('textbox', {name: 'Add or Invite People'}).
cy.findByRole('combobox', {name: 'Add or Invite People'}).
typeWithForce(email).
wait(TIMEOUTS.HALF_SEC).
typeWithForce('{enter}');
Expand Down
2 changes: 1 addition & 1 deletion e2e-tests/cypress/tests/support/ui/channel.js
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ Cypress.Commands.add('goToDm', (username) => {
// # Start typing part of a username that matches previously created users
cy.get('#selectItems input').typeWithForce(username);
cy.findByRole('dialog', {name: 'Direct Messages'}).should('be.visible').wait(TIMEOUTS.ONE_SEC);
cy.findByRole('textbox', {name: 'Search for people'}).
cy.findByRole('combobox', {name: 'Search for people'}).
typeWithForce(username).
wait(TIMEOUTS.ONE_SEC).
typeWithForce('{enter}');
Expand Down
4 changes: 2 additions & 2 deletions e2e-tests/cypress/tests/support/ui/data_retention.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ Cypress.Commands.add('uiFillOutCustomPolicyFields', (name, durationDropdown, dur
Cypress.Commands.add('uiAddTeamsToCustomPolicy', (teamNames) => {
cy.uiGetButton('Add teams').click();
teamNames.forEach((teamName) => {
cy.findByRole('textbox', {name: 'Search and add teams'}).typeWithForce(teamName);
cy.findByRole('combobox', {name: 'Search and add teams'}).typeWithForce(teamName);
cy.get('.team-info-block').then((el) => {
el.click();
});
Expand All @@ -39,7 +39,7 @@ Cypress.Commands.add('uiAddTeamsToCustomPolicy', (teamNames) => {
Cypress.Commands.add('uiAddChannelsToCustomPolicy', (channelNames) => {
cy.uiGetButton('Add channels').click();
channelNames.forEach((channelName) => {
cy.findByRole('textbox', {name: 'Search and add channels'}).typeWithForce(channelName);
cy.findByRole('combobox', {name: 'Search and add channels'}).typeWithForce(channelName);
cy.wait(TIMEOUTS.ONE_SEC);
cy.get('.channel-info-block').then((el) => {
el.click();
Expand Down
2 changes: 1 addition & 1 deletion e2e-tests/cypress/tests/support/ui_commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ function uiGotoDirectMessageWithUser(user: User) {
cy.findByRole('dialog', {name: 'Direct Messages'}).should('be.visible').wait(TIMEOUTS.ONE_SEC);

// # Type username
cy.findByRole('textbox', {name: 'Search for people'}).click({force: true}).
cy.findByRole('combobox', {name: 'Search for people'}).click({force: true}).
type(user.username, {force: true}).wait(TIMEOUTS.ONE_SEC);

// * Expect user count in the list to be 1
Expand Down
3 changes: 1 addition & 2 deletions webapp/channels/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@
"react-popper": "2.3.0",
"react-redux": "7.2.4",
"react-router-dom": "5.3.4",
"react-select": "3.0.3",
"react-select": "5.9.0",
"react-transition-group": "4.4.5",
"react-virtualized-auto-sizer": "1.0.7",
"react-window": "1.8.8",
Expand Down Expand Up @@ -130,7 +130,6 @@
"@types/react-overlays": "1.1.3",
"@types/react-redux": "7.1.31",
"@types/react-router-dom": "5.3.3",
"@types/react-select": "3.0.19",
"@types/react-transition-group": "4.4.5",
"@types/react-virtualized-auto-sizer": "1.0.1",
"@types/react-window": "1.8.5",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -422,7 +422,7 @@ exports[`components/admin_console/SchemaAdminSettings should match snapshot with
id="SecondSettings.settingj"
key="Config_language_SecondSettings.settingj"
label="label-j"
noResultText="no-result-j"
noOptionsMessage="no-result-j"
onChange={[Function]}
selected={Array []}
setByEnv={false}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import React, {createRef} from 'react';
import type {RefObject} from 'react';
import type {WrappedComponentProps} from 'react-intl';
import {FormattedMessage, defineMessages, injectIntl} from 'react-intl';
import type {SelectInstance} from 'react-select';
import ReactSelect from 'react-select';

import type {AdminConfig} from '@mattermost/types/config';
Expand Down Expand Up @@ -81,7 +82,7 @@ export const searchableStrings = [
];

class DataRetentionSettings extends React.PureComponent<Props, State> {
inputRef: RefObject<ReactSelect<OptionType>>;
inputRef: RefObject<SelectInstance<OptionType>>;
constructor(props: Props) {
super(props);
this.inputRef = createRef();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ export default class GlobalPolicyForm extends React.PureComponent<Props, State>
inputValue={this.state.messageRetentionInputValue}
width={90}
exceptionToInput={[FOREVER]}
disabled={this.isMessageRetentionSetByEnv()}
isDisabled={this.isMessageRetentionSetByEnv()}
defaultValue={keepForeverOption()}
options={[hoursOption(), daysOption(), yearsOption(), keepForeverOption()]}
legend={messages.channelAndMessageRetention}
Expand Down Expand Up @@ -242,7 +242,7 @@ export default class GlobalPolicyForm extends React.PureComponent<Props, State>
inputValue={this.state.fileRetentionInputValue}
width={90}
exceptionToInput={[FOREVER]}
disabled={this.isFileRetentionSetByEnv()}
isDisabled={this.isFileRetentionSetByEnv()}
defaultValue={keepForeverOption()}
options={[hoursOption(), daysOption(), yearsOption(), keepForeverOption()]}
legend={messages.fileRetention}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

import React, {useEffect, useState} from 'react';
import {useIntl} from 'react-intl';
import type {ActionMeta, OptionsType, ValueType} from 'react-select';
import type {ActionMeta, Options, OnChangeValue} from 'react-select';
import AsyncSelect from 'react-select/async';

import type {PagedTeamSearchOpts, Team} from '@mattermost/types/teams';
Expand All @@ -28,7 +28,7 @@ export interface Props extends PropsFromRedux {
function TeamFilterDropdown(props: Props) {
const {formatMessage} = useIntl();

const [list, setList] = useState<OptionsType<TeamSelectOption>>([]);
const [list, setList] = useState<Options<TeamSelectOption>>([]);
const [pageNumber, setPageNumber] = useState(0);

async function loadListInPageNumber(page: number) {
Expand All @@ -55,7 +55,7 @@ function TeamFilterDropdown(props: Props) {
}
}

async function searchInList(term: string, callBack: (options: OptionsType<{label: string; value: string}>) => void) {
async function searchInList(term: string) {
try {
const response = await props.searchTeams(term, {page: 0, per_page: TEAMS_PER_PAGE} as PagedTeamSearchOpts);
if (response && response.data && response.data.teams && response.data.teams.length > 0) {
Expand All @@ -64,21 +64,21 @@ function TeamFilterDropdown(props: Props) {
label: team.display_name,
}));

callBack(teams);
return teams;
}

callBack([]);
return [];
} catch (error) {
console.error(error); // eslint-disable-line no-console
callBack([]);
return [];
}
}

function handleMenuScrolledToBottom() {
loadListInPageNumber(pageNumber);
}

function handleOnChange(value: ValueType<TeamSelectOption>, actionMeta: ActionMeta<TeamSelectOption>) {
function handleOnChange(value: OnChangeValue<TeamSelectOption, true>, actionMeta: ActionMeta<TeamSelectOption>) {
if (!actionMeta.action) {
return;
}
Expand Down
Loading

0 comments on commit 8e9a09e

Please sign in to comment.