[MM-61647][MM-61651]: Upgraded react-select to v5 (#30070)
* [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>
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
6ecaad2a41
Коммит
8e9a09e512
@@ -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', () => {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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).
|
||||
@@ -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).
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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});
|
||||
|
||||
@@ -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});
|
||||
|
||||
@@ -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');
|
||||
|
||||
@@ -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');
|
||||
|
||||
@@ -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');
|
||||
|
||||
@@ -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);
|
||||
});
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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}');
|
||||
|
||||
@@ -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}');
|
||||
|
||||
@@ -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();
|
||||
});
|
||||
@@ -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();
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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",
|
||||
@@ -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",
|
||||
|
||||
@@ -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}
|
||||
|
||||
@@ -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';
|
||||
@@ -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();
|
||||
|
||||
@@ -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}
|
||||
@@ -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}
|
||||
|
||||
@@ -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';
|
||||
@@ -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) {
|
||||
@@ -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) {
|
||||
@@ -64,13 +64,13 @@ 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 [];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,7 +78,7 @@ function TeamFilterDropdown(props: Props) {
|
||||
loadListInPageNumber(pageNumber);
|
||||
}
|
||||
|
||||
function handleOnChange(value: ValueType<TeamSelectOption>, actionMeta: ActionMeta<TeamSelectOption>) {
|
||||
function handleOnChange(value: OnChangeValue<TeamSelectOption, true>, actionMeta: ActionMeta<TeamSelectOption>) {
|
||||
if (!actionMeta.action) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ import type {DropResult} from 'react-beautiful-dnd';
|
||||
import {DragDropContext, Draggable, Droppable} from 'react-beautiful-dnd';
|
||||
import {FormattedMessage, defineMessages, useIntl} from 'react-intl';
|
||||
import ReactSelect, {components} from 'react-select';
|
||||
import type {IndicatorContainerProps, ValueType} from 'react-select';
|
||||
import type {IndicatorsContainerProps, OnChangeValue} from 'react-select';
|
||||
|
||||
import {DragVerticalIcon} from '@mattermost/compass-icons/components';
|
||||
|
||||
@@ -107,7 +107,7 @@ export function ListTable<TableType extends TableMandatoryTypes>(
|
||||
|
||||
const selectedPageSize = pageSizeOptions.find((option) => option.value === props.table.getState().pagination.pageSize) || pageSizeOptions[0];
|
||||
|
||||
function handlePageSizeChange(selectedOption: ValueType<PageSizeOption>) {
|
||||
function handlePageSizeChange(selectedOption: OnChangeValue<PageSizeOption, false>) {
|
||||
const {value} = selectedOption as PageSizeOption;
|
||||
props.table.setPageSize(Number(value));
|
||||
}
|
||||
@@ -370,7 +370,7 @@ export function ListTable<TableType extends TableMandatoryTypes>(
|
||||
);
|
||||
}
|
||||
|
||||
function IndicatorsContainer(props: IndicatorContainerProps<PageSizeOption>) {
|
||||
function IndicatorsContainer(props: IndicatorsContainerProps<PageSizeOption>) {
|
||||
return (
|
||||
<components.IndicatorsContainer {...props}>
|
||||
<i className='icon icon-chevron-down'/>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import React, {useState, useCallback, useMemo} from 'react';
|
||||
import type {ValueType} from 'react-select';
|
||||
import type {OnChangeValue} from 'react-select';
|
||||
import ReactSelect from 'react-select';
|
||||
|
||||
import FormError from 'components/form_error';
|
||||
@@ -23,7 +23,7 @@ interface Props {
|
||||
disabled?: boolean;
|
||||
setByEnv: boolean;
|
||||
helpText?: React.ReactNode;
|
||||
noResultText?: React.ReactNode;
|
||||
noOptionsMessage?: React.ReactNode;
|
||||
}
|
||||
|
||||
const getOptionLabel = ({text}: { text: string}) => text;
|
||||
@@ -37,11 +37,11 @@ const MultiSelectSetting: React.FC<Props> = ({
|
||||
disabled = false,
|
||||
setByEnv,
|
||||
helpText,
|
||||
noResultText,
|
||||
noOptionsMessage,
|
||||
}) => {
|
||||
const [error, setError] = useState(false);
|
||||
|
||||
const handleChange = useCallback((newValue: ValueType<Option>) => {
|
||||
const handleChange = useCallback((newValue: OnChangeValue<Option, true>) => {
|
||||
const updatedValues = newValue ? (newValue as Option[]).map((n) => {
|
||||
return n.value;
|
||||
}) : [];
|
||||
@@ -80,9 +80,9 @@ const MultiSelectSetting: React.FC<Props> = ({
|
||||
getOptionLabel={getOptionLabel}
|
||||
options={values}
|
||||
delimiter={','}
|
||||
clearable={false}
|
||||
isClearable={false}
|
||||
isDisabled={disabled || setByEnv}
|
||||
noResultsText={noResultText}
|
||||
noOptionsMessage={() => noOptionsMessage}
|
||||
onChange={handleChange}
|
||||
value={calculatedValue}
|
||||
/>
|
||||
|
||||
@@ -665,7 +665,7 @@ export class SchemaAdminSettings extends React.PureComponent<Props, State> {
|
||||
});
|
||||
|
||||
if (setting.multiple) {
|
||||
const noResultText = typeof setting.no_result === 'object' ? (
|
||||
const noOptionsMessage = typeof setting.no_result === 'object' ? (
|
||||
<FormattedMessage {...setting.no_result}/>
|
||||
) : setting.no_result;
|
||||
return (
|
||||
@@ -679,7 +679,7 @@ export class SchemaAdminSettings extends React.PureComponent<Props, State> {
|
||||
disabled={this.isDisabled(setting)}
|
||||
setByEnv={this.isSetByEnv(setting.key)}
|
||||
onChange={this.handleChange}
|
||||
noResultText={noResultText}
|
||||
noOptionsMessage={noOptionsMessage}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@@ -721,7 +721,7 @@ export class SchemaAdminSettings extends React.PureComponent<Props, State> {
|
||||
disabled={this.isDisabled(setting)}
|
||||
setByEnv={this.isSetByEnv(setting.key)}
|
||||
onChange={(changedId, value) => this.handleChange(changedId, value.join(','))}
|
||||
noResultText={descriptorOrStringToString(setting.no_result, this.props.intl)}
|
||||
noOptionsMessage={descriptorOrStringToString(setting.no_result, this.props.intl)}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -61,7 +61,6 @@ export function SystemUsersFiltersStatus(props: Props) {
|
||||
return (
|
||||
<DropdownInput<OptionType>
|
||||
name='filterStatus'
|
||||
showLegend={true}
|
||||
isSearchable={false}
|
||||
legend={formatMessage({id: 'admin.system_users.filters.status.title', defaultMessage: 'Status'})}
|
||||
options={options}
|
||||
|
||||
@@ -68,7 +68,6 @@ export function SystemUsersFilterRole(props: Props) {
|
||||
return (
|
||||
<DropdownInput<OptionType>
|
||||
name='filterRole'
|
||||
showLegend={true}
|
||||
isSearchable={false}
|
||||
legend={formatMessage({id: 'admin.system_users.filters.role.title', defaultMessage: 'Role'})}
|
||||
options={options}
|
||||
|
||||
@@ -2,12 +2,12 @@
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import classNames from 'classnames';
|
||||
import type {CSSProperties, ReactElement} from 'react';
|
||||
import type {ReactElement} from 'react';
|
||||
import React, {useEffect, useState} from 'react';
|
||||
import {useIntl} from 'react-intl';
|
||||
import {useDispatch} from 'react-redux';
|
||||
import {components} from 'react-select';
|
||||
import type {IndicatorContainerProps, ControlProps, OptionProps, OptionsType, ValueType, StylesConfig} from 'react-select';
|
||||
import type {IndicatorsContainerProps, ControlProps, OptionProps, Options, OnChangeValue, StylesConfig} from 'react-select';
|
||||
import AsyncSelect from 'react-select/async';
|
||||
|
||||
import type {Team, TeamSearchOpts} from '@mattermost/types/teams';
|
||||
@@ -45,9 +45,9 @@ export function SystemUsersFilterTeam(props: Props) {
|
||||
|
||||
const [error, setError] = useState('');
|
||||
|
||||
const [list, setList] = useState<OptionsType<OptionType>>();
|
||||
const [list, setList] = useState<Options<OptionType>>();
|
||||
const [pageNumber, setPageNumber] = useState(0);
|
||||
const [value, setValue] = useState<ValueType<OptionType>>(getDefaultSelectedTeam(props.initialValue, props.initialLabel));
|
||||
const [value, setValue] = useState<OnChangeValue<OptionType, false>>(getDefaultSelectedTeam(props.initialValue, props.initialLabel));
|
||||
|
||||
async function loadListInPageNumber(page: number) {
|
||||
try {
|
||||
@@ -84,7 +84,7 @@ export function SystemUsersFilterTeam(props: Props) {
|
||||
}
|
||||
}
|
||||
|
||||
async function searchInList(term: string, callBack: (options: OptionsType<{label: string; value: string}>) => void) {
|
||||
async function searchInList(term: string) {
|
||||
try {
|
||||
const response = await dispatch(searchTeams(term, {page: 0, per_page: TEAMS_PER_PAGE} as TeamSearchOpts));
|
||||
if (response && response.data && response.data.teams && response.data.teams.length > 0) {
|
||||
@@ -93,14 +93,14 @@ export function SystemUsersFilterTeam(props: Props) {
|
||||
label: team.display_name,
|
||||
}));
|
||||
|
||||
callBack(teams);
|
||||
return teams;
|
||||
}
|
||||
|
||||
callBack([]);
|
||||
return [];
|
||||
} catch (error) {
|
||||
setError(formatMessage({id: 'admin.system_users.filters.team.errorSearching', defaultMessage: 'Error while searching teams'}));
|
||||
console.error(error); // eslint-disable-line no-console
|
||||
callBack([]);
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -108,7 +108,7 @@ export function SystemUsersFilterTeam(props: Props) {
|
||||
loadListInPageNumber(pageNumber);
|
||||
}
|
||||
|
||||
function handleOnChange(value: ValueType<OptionType>) {
|
||||
function handleOnChange(value: OnChangeValue<OptionType, false>) {
|
||||
setValue(value);
|
||||
props.onChange((value as OptionType).value as string, (value as OptionType).label as string);
|
||||
}
|
||||
@@ -164,33 +164,33 @@ export function SystemUsersFilterTeam(props: Props) {
|
||||
);
|
||||
}
|
||||
|
||||
const styles: Partial<StylesConfig> = {
|
||||
input: (provided: CSSProperties) => ({
|
||||
const styles = {
|
||||
input: (provided) => ({
|
||||
...provided,
|
||||
color: 'var(--center-channel-color)',
|
||||
}),
|
||||
control: (provided: CSSProperties) => ({
|
||||
control: (provided) => ({
|
||||
...provided,
|
||||
border: 'none',
|
||||
boxShadow: 'none',
|
||||
padding: '0 2px',
|
||||
cursor: 'pointer',
|
||||
}),
|
||||
indicatorSeparator: (provided: CSSProperties) => ({
|
||||
indicatorSeparator: (provided) => ({
|
||||
...provided,
|
||||
display: 'none',
|
||||
}),
|
||||
menu: (provided: CSSProperties) => ({
|
||||
menu: (provided) => ({
|
||||
...provided,
|
||||
zIndex: 100,
|
||||
}),
|
||||
menuPortal: (provided: CSSProperties) => ({
|
||||
menuPortal: (provided) => ({
|
||||
...provided,
|
||||
zIndex: 100,
|
||||
}),
|
||||
};
|
||||
} satisfies Partial<StylesConfig<OptionType, false>>;
|
||||
|
||||
const IndicatorsContainer = (props: IndicatorContainerProps<OptionType>) => {
|
||||
const IndicatorsContainer = (props: IndicatorsContainerProps<OptionType, false>) => {
|
||||
return (
|
||||
<div className='asyncTeamSelectInput__indicatorsContainer'>
|
||||
<components.IndicatorsContainer {...props}>
|
||||
@@ -200,7 +200,7 @@ const IndicatorsContainer = (props: IndicatorContainerProps<OptionType>) => {
|
||||
);
|
||||
};
|
||||
|
||||
const Control = (props: ControlProps<OptionType>) => {
|
||||
const Control = (props: ControlProps<OptionType, false>) => {
|
||||
return (
|
||||
<div className='asyncTeamSelectInput__controlContainer'>
|
||||
<components.Control {...props}/>
|
||||
@@ -208,7 +208,7 @@ const Control = (props: ControlProps<OptionType>) => {
|
||||
);
|
||||
};
|
||||
|
||||
const Option = (props: OptionProps<OptionType>) => {
|
||||
const Option = (props: OptionProps<OptionType, false>) => {
|
||||
return (
|
||||
<div
|
||||
className={classNames('asyncTeamSelectInput__option', {
|
||||
|
||||
@@ -2,12 +2,14 @@
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import React from 'react';
|
||||
import type {StylesConfig} from 'react-select';
|
||||
import ReactSelect from 'react-select';
|
||||
import AsyncSelect from 'react-select/async';
|
||||
|
||||
import type {AppField, AppSelectOption} from '@mattermost/types/apps';
|
||||
import type {UserAutocomplete} from '@mattermost/types/autocomplete';
|
||||
import type {Channel} from '@mattermost/types/channels';
|
||||
import type {UserProfile} from '@mattermost/types/users';
|
||||
|
||||
import {AppFieldTypes} from 'mattermost-redux/constants/apps';
|
||||
import type {ActionResult} from 'mattermost-redux/types/actions';
|
||||
@@ -22,7 +24,7 @@ export type Props = {
|
||||
field: AppField;
|
||||
label: React.ReactNode;
|
||||
helpText: React.ReactNode;
|
||||
value: AppSelectOption | null;
|
||||
value: AppSelectOption | UserProfile | Channel | null;
|
||||
onChange: (value: AppSelectOption) => void;
|
||||
performLookup: (name: string, userInput: string) => Promise<AppSelectOption[]>;
|
||||
teammateNameDisplay?: string;
|
||||
@@ -38,14 +40,14 @@ export type State = {
|
||||
}
|
||||
|
||||
const reactStyles = {
|
||||
menuPortal: (provided: React.CSSProperties) => ({
|
||||
menuPortal: (provided) => ({
|
||||
...provided,
|
||||
zIndex: 9999,
|
||||
}),
|
||||
};
|
||||
} satisfies StylesConfig<AppSelectOption | UserProfile | Channel >;
|
||||
|
||||
const commonComponents = {
|
||||
MultiValueLabel: (props: {data: {label: string}}) => (
|
||||
MultiValueLabel: (props: { data: { label: string } }) => (
|
||||
<div className='react-select__padded-component'>
|
||||
{props.data.label}
|
||||
</div>
|
||||
@@ -57,7 +59,7 @@ const commonProps = {
|
||||
openMenuOnFocus: false,
|
||||
classNamePrefix: 'react-select-auto react-select',
|
||||
menuPortalTarget: document.body,
|
||||
styles: reactStyles,
|
||||
styles: reactStyles satisfies StylesConfig<AppSelectOption | UserProfile | Channel>,
|
||||
};
|
||||
|
||||
export default class AppsFormSelectField extends React.PureComponent<Props, State> {
|
||||
@@ -88,7 +90,7 @@ export default class AppsFormSelectField extends React.PureComponent<Props, Stat
|
||||
return this.props.performLookup(this.props.field.name, userInput);
|
||||
};
|
||||
|
||||
loadDynamicUserOptions = async (userInput: string): Promise<AppSelectOption[]> => {
|
||||
loadDynamicUserOptions = async (userInput: string): Promise<UserProfile[]> => {
|
||||
const usersSearchResults: UserAutocomplete = await this.props.actions.autocompleteUsers(userInput.toLowerCase());
|
||||
|
||||
return usersSearchResults.users.filter((user) => !user.is_bot).map((user) => {
|
||||
@@ -98,7 +100,7 @@ export default class AppsFormSelectField extends React.PureComponent<Props, Stat
|
||||
});
|
||||
};
|
||||
|
||||
loadDynamicChannelOptions = async (userInput: string): Promise<AppSelectOption[]> => {
|
||||
loadDynamicChannelOptions = async (userInput: string): Promise<Channel[]> => {
|
||||
let channelsSearchResults: Channel[] = [];
|
||||
|
||||
await this.props.actions.autocompleteChannels(userInput.toLowerCase(), (data) => {
|
||||
@@ -111,11 +113,11 @@ export default class AppsFormSelectField extends React.PureComponent<Props, Stat
|
||||
renderDynamicSelect() {
|
||||
const {field} = this.props;
|
||||
const placeholder = field.hint || '';
|
||||
const value = this.props.value;
|
||||
const value = this.props.value as AppSelectOption;
|
||||
|
||||
return (
|
||||
<div className={'react-select'}>
|
||||
<AsyncSelect
|
||||
<AsyncSelect<AppSelectOption, boolean>
|
||||
id={`MultiInput_${field.name}`}
|
||||
loadOptions={this.loadDynamicOptions}
|
||||
defaultOptions={true}
|
||||
@@ -134,11 +136,11 @@ export default class AppsFormSelectField extends React.PureComponent<Props, Stat
|
||||
renderUserSelect() {
|
||||
const {hint, name, multiselect, readonly} = this.props.field;
|
||||
const placeholder = hint || '';
|
||||
const value = this.props.value;
|
||||
const value = this.props.value as UserProfile;
|
||||
|
||||
return (
|
||||
<div className={'react-select'}>
|
||||
<AsyncSelect
|
||||
<AsyncSelect<UserProfile, boolean>
|
||||
id={`MultiInput_${name}`}
|
||||
loadOptions={this.loadDynamicUserOptions}
|
||||
defaultOptions={true}
|
||||
@@ -157,11 +159,11 @@ export default class AppsFormSelectField extends React.PureComponent<Props, Stat
|
||||
renderChannelSelect() {
|
||||
const {hint, name, multiselect, readonly} = this.props.field;
|
||||
const placeholder = hint || '';
|
||||
const value = this.props.value;
|
||||
const value = this.props.value as Channel;
|
||||
|
||||
return (
|
||||
<div className={'react-select'}>
|
||||
<AsyncSelect
|
||||
<AsyncSelect<Channel, boolean>
|
||||
id={`MultiInput_${name}`}
|
||||
loadOptions={this.loadDynamicChannelOptions}
|
||||
defaultOptions={true}
|
||||
|
||||
@@ -5,10 +5,10 @@ import React from 'react';
|
||||
import {components} from 'react-select';
|
||||
import type {OptionProps} from 'react-select';
|
||||
|
||||
import type {AppSelectOption} from '@mattermost/types/apps';
|
||||
import type {Channel} from '@mattermost/types/channels';
|
||||
|
||||
const {Option} = components;
|
||||
export const SelectChannelOption = (props: OptionProps<AppSelectOption>) => {
|
||||
export const SelectChannelOption = (props: OptionProps<Channel>) => {
|
||||
const item = props.data;
|
||||
|
||||
const channelName = item.display_name;
|
||||
|
||||
@@ -5,7 +5,6 @@ import React from 'react';
|
||||
import {components} from 'react-select';
|
||||
import type {OptionProps} from 'react-select';
|
||||
|
||||
import type {AppSelectOption} from '@mattermost/types/apps';
|
||||
import type {UserProfile} from '@mattermost/types/users';
|
||||
|
||||
import {isGuest} from 'mattermost-redux/utils/user_utils';
|
||||
@@ -30,7 +29,7 @@ const getDescription = (data: UserProfile): string => {
|
||||
|
||||
const {Option} = components;
|
||||
|
||||
export const SelectUserOption = (props: OptionProps<AppSelectOption>) => {
|
||||
export const SelectUserOption = (props: OptionProps<UserProfile>) => {
|
||||
const username = props.data.username;
|
||||
const description = getDescription(props.data);
|
||||
|
||||
|
||||
@@ -721,38 +721,55 @@ Object {
|
||||
class="mm-modal-generic-section-item__fieldset-react-select"
|
||||
>
|
||||
<div
|
||||
class="react-select singleSelect react-select-top css-2b097c-container"
|
||||
class="react-select singleSelect react-select-top css-b62m3t-container"
|
||||
id="desktopNotificationSoundsSelect"
|
||||
>
|
||||
<span
|
||||
class="css-1f43avz-a11yText-A11yText"
|
||||
id="react-select-8-live-region"
|
||||
/>
|
||||
<span
|
||||
aria-atomic="false"
|
||||
aria-live="polite"
|
||||
aria-relevant="additions text"
|
||||
class="css-1f43avz-a11yText-A11yText"
|
||||
role="log"
|
||||
/>
|
||||
<div
|
||||
class="react-select__control css-yk16xz-control"
|
||||
class="react-select__control css-13cymwt-control"
|
||||
>
|
||||
<div
|
||||
class="react-select__value-container react-select__value-container--has-value css-1hwfws3"
|
||||
class="react-select__value-container react-select__value-container--has-value css-hlgwow"
|
||||
>
|
||||
<div
|
||||
class="react-select__single-value css-1uccc91-singleValue"
|
||||
class="react-select__single-value css-1dimb5e-singleValue"
|
||||
>
|
||||
Bing
|
||||
</div>
|
||||
<input
|
||||
class="css-62g3xt-dummyInput"
|
||||
aria-activedescendant=""
|
||||
aria-autocomplete="list"
|
||||
aria-expanded="false"
|
||||
aria-haspopup="true"
|
||||
aria-readonly="true"
|
||||
class="css-1s80ejz-dummyInput-DummyInput"
|
||||
id="desktopNotificationSoundsSelectInputId"
|
||||
readonly=""
|
||||
inputmode="none"
|
||||
role="combobox"
|
||||
tabindex="0"
|
||||
value=""
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="react-select__indicators css-1hb7zxy-IndicatorsContainer"
|
||||
class="react-select__indicators css-1wy0on6"
|
||||
>
|
||||
<div
|
||||
aria-hidden="true"
|
||||
class="react-select__indicator react-select__dropdown-indicator css-tlfecz-indicatorContainer"
|
||||
class="react-select__indicator react-select__dropdown-indicator css-1xc3v61-indicatorContainer"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
class="css-6q0nyr-Svg"
|
||||
class="css-tj5bde-Svg"
|
||||
focusable="false"
|
||||
height="20"
|
||||
viewBox="0 0 20 20"
|
||||
@@ -1624,38 +1641,55 @@ Object {
|
||||
class="mm-modal-generic-section-item__fieldset-react-select"
|
||||
>
|
||||
<div
|
||||
class="react-select singleSelect react-select-top css-2b097c-container"
|
||||
class="react-select singleSelect react-select-top css-b62m3t-container"
|
||||
id="desktopNotificationSoundsSelect"
|
||||
>
|
||||
<span
|
||||
class="css-1f43avz-a11yText-A11yText"
|
||||
id="react-select-3-live-region"
|
||||
/>
|
||||
<span
|
||||
aria-atomic="false"
|
||||
aria-live="polite"
|
||||
aria-relevant="additions text"
|
||||
class="css-1f43avz-a11yText-A11yText"
|
||||
role="log"
|
||||
/>
|
||||
<div
|
||||
class="react-select__control css-yk16xz-control"
|
||||
class="react-select__control css-13cymwt-control"
|
||||
>
|
||||
<div
|
||||
class="react-select__value-container react-select__value-container--has-value css-1hwfws3"
|
||||
class="react-select__value-container react-select__value-container--has-value css-hlgwow"
|
||||
>
|
||||
<div
|
||||
class="react-select__single-value css-1uccc91-singleValue"
|
||||
class="react-select__single-value css-1dimb5e-singleValue"
|
||||
>
|
||||
Bing
|
||||
</div>
|
||||
<input
|
||||
class="css-62g3xt-dummyInput"
|
||||
aria-activedescendant=""
|
||||
aria-autocomplete="list"
|
||||
aria-expanded="false"
|
||||
aria-haspopup="true"
|
||||
aria-readonly="true"
|
||||
class="css-1s80ejz-dummyInput-DummyInput"
|
||||
id="desktopNotificationSoundsSelectInputId"
|
||||
readonly=""
|
||||
inputmode="none"
|
||||
role="combobox"
|
||||
tabindex="0"
|
||||
value=""
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="react-select__indicators css-1hb7zxy-IndicatorsContainer"
|
||||
class="react-select__indicators css-1wy0on6"
|
||||
>
|
||||
<div
|
||||
aria-hidden="true"
|
||||
class="react-select__indicator react-select__dropdown-indicator css-tlfecz-indicatorContainer"
|
||||
class="react-select__indicator react-select__dropdown-indicator css-1xc3v61-indicatorContainer"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
class="css-6q0nyr-Svg"
|
||||
class="css-tj5bde-Svg"
|
||||
focusable="false"
|
||||
height="20"
|
||||
viewBox="0 0 20 20"
|
||||
@@ -2146,38 +2180,55 @@ Object {
|
||||
class="mm-modal-generic-section-item__fieldset-react-select"
|
||||
>
|
||||
<div
|
||||
class="react-select singleSelect react-select-top css-2b097c-container"
|
||||
class="react-select singleSelect react-select-top css-b62m3t-container"
|
||||
id="desktopNotificationSoundsSelect"
|
||||
>
|
||||
<span
|
||||
class="css-1f43avz-a11yText-A11yText"
|
||||
id="react-select-7-live-region"
|
||||
/>
|
||||
<span
|
||||
aria-atomic="false"
|
||||
aria-live="polite"
|
||||
aria-relevant="additions text"
|
||||
class="css-1f43avz-a11yText-A11yText"
|
||||
role="log"
|
||||
/>
|
||||
<div
|
||||
class="react-select__control css-yk16xz-control"
|
||||
class="react-select__control css-13cymwt-control"
|
||||
>
|
||||
<div
|
||||
class="react-select__value-container react-select__value-container--has-value css-1hwfws3"
|
||||
class="react-select__value-container react-select__value-container--has-value css-hlgwow"
|
||||
>
|
||||
<div
|
||||
class="react-select__single-value css-1uccc91-singleValue"
|
||||
class="react-select__single-value css-1dimb5e-singleValue"
|
||||
>
|
||||
Bing
|
||||
</div>
|
||||
<input
|
||||
class="css-62g3xt-dummyInput"
|
||||
aria-activedescendant=""
|
||||
aria-autocomplete="list"
|
||||
aria-expanded="false"
|
||||
aria-haspopup="true"
|
||||
aria-readonly="true"
|
||||
class="css-1s80ejz-dummyInput-DummyInput"
|
||||
id="desktopNotificationSoundsSelectInputId"
|
||||
readonly=""
|
||||
inputmode="none"
|
||||
role="combobox"
|
||||
tabindex="0"
|
||||
value=""
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="react-select__indicators css-1hb7zxy-IndicatorsContainer"
|
||||
class="react-select__indicators css-1wy0on6"
|
||||
>
|
||||
<div
|
||||
aria-hidden="true"
|
||||
class="react-select__indicator react-select__dropdown-indicator css-tlfecz-indicatorContainer"
|
||||
class="react-select__indicator react-select__dropdown-indicator css-1xc3v61-indicatorContainer"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
class="css-6q0nyr-Svg"
|
||||
class="css-tj5bde-Svg"
|
||||
focusable="false"
|
||||
height="20"
|
||||
viewBox="0 0 20 20"
|
||||
@@ -2668,38 +2719,55 @@ Object {
|
||||
class="mm-modal-generic-section-item__fieldset-react-select"
|
||||
>
|
||||
<div
|
||||
class="react-select singleSelect react-select-top css-2b097c-container"
|
||||
class="react-select singleSelect react-select-top css-b62m3t-container"
|
||||
id="desktopNotificationSoundsSelect"
|
||||
>
|
||||
<span
|
||||
class="css-1f43avz-a11yText-A11yText"
|
||||
id="react-select-9-live-region"
|
||||
/>
|
||||
<span
|
||||
aria-atomic="false"
|
||||
aria-live="polite"
|
||||
aria-relevant="additions text"
|
||||
class="css-1f43avz-a11yText-A11yText"
|
||||
role="log"
|
||||
/>
|
||||
<div
|
||||
class="react-select__control css-yk16xz-control"
|
||||
class="react-select__control css-13cymwt-control"
|
||||
>
|
||||
<div
|
||||
class="react-select__value-container react-select__value-container--has-value css-1hwfws3"
|
||||
class="react-select__value-container react-select__value-container--has-value css-hlgwow"
|
||||
>
|
||||
<div
|
||||
class="react-select__single-value css-1uccc91-singleValue"
|
||||
class="react-select__single-value css-1dimb5e-singleValue"
|
||||
>
|
||||
Bing
|
||||
</div>
|
||||
<input
|
||||
class="css-62g3xt-dummyInput"
|
||||
aria-activedescendant=""
|
||||
aria-autocomplete="list"
|
||||
aria-expanded="false"
|
||||
aria-haspopup="true"
|
||||
aria-readonly="true"
|
||||
class="css-1s80ejz-dummyInput-DummyInput"
|
||||
id="desktopNotificationSoundsSelectInputId"
|
||||
readonly=""
|
||||
inputmode="none"
|
||||
role="combobox"
|
||||
tabindex="0"
|
||||
value=""
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="react-select__indicators css-1hb7zxy-IndicatorsContainer"
|
||||
class="react-select__indicators css-1wy0on6"
|
||||
>
|
||||
<div
|
||||
aria-hidden="true"
|
||||
class="react-select__indicator react-select__dropdown-indicator css-tlfecz-indicatorContainer"
|
||||
class="react-select__indicator react-select__dropdown-indicator css-1xc3v61-indicatorContainer"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
class="css-6q0nyr-Svg"
|
||||
class="css-tj5bde-Svg"
|
||||
focusable="false"
|
||||
height="20"
|
||||
viewBox="0 0 20 20"
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
import React, {useCallback, useState} from 'react';
|
||||
import {Modal} from 'react-bootstrap';
|
||||
import {FormattedMessage, useIntl} from 'react-intl';
|
||||
import type {ValueType} from 'react-select';
|
||||
import type {OnChangeValue} from 'react-select';
|
||||
|
||||
import {BellOffOutlineIcon} from '@mattermost/compass-icons/components';
|
||||
import type {Channel, ChannelMembership, ChannelNotifyProps} from '@mattermost/types/channels';
|
||||
@@ -149,7 +149,7 @@ export default function ChannelNotificationsModal(props: Props) {
|
||||
</>
|
||||
);
|
||||
|
||||
const handleChangeForMessageNotificationSoundSelect = (selectedOption: ValueType<Option>) => {
|
||||
const handleChangeForMessageNotificationSoundSelect = (selectedOption: OnChangeValue<Option, boolean>) => {
|
||||
stopTryNotificationRing();
|
||||
|
||||
if (selectedOption && 'value' in selectedOption) {
|
||||
|
||||
@@ -2,7 +2,8 @@
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import React, {useCallback, useMemo} from 'react';
|
||||
import type {CSSProperties, KeyboardEventHandler} from 'react';
|
||||
import type {KeyboardEventHandler} from 'react';
|
||||
import type {StylesConfig} from 'react-select';
|
||||
import CreatableSelect from 'react-select/creatable';
|
||||
|
||||
import './select_text_input.scss';
|
||||
@@ -27,22 +28,22 @@ type Props = {
|
||||
}
|
||||
|
||||
const styles = {
|
||||
control: (baseStyles: CSSProperties) => ({
|
||||
control: (baseStyles) => ({
|
||||
...baseStyles,
|
||||
background: 'var(--center-channel-color-rgb)',
|
||||
}),
|
||||
input: (baseStyles: CSSProperties) => ({
|
||||
input: (baseStyles) => ({
|
||||
...baseStyles,
|
||||
color: 'rgba(var(--center-channel-color-rgb), 0.64)',
|
||||
}),
|
||||
multiValue: (baseStyles: CSSProperties) => ({
|
||||
multiValue: (baseStyles) => ({
|
||||
...baseStyles,
|
||||
borderRadius: '10px',
|
||||
background: 'rgba(var(--center-channel-color-rgb), 0.08)',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
}),
|
||||
multiValueLabel: (baseStyles: CSSProperties) => ({
|
||||
multiValueLabel: (baseStyles) => ({
|
||||
...baseStyles,
|
||||
padding: '4px 6px 4px 10px',
|
||||
color: 'var(--center-channel-color)',
|
||||
@@ -52,7 +53,7 @@ const styles = {
|
||||
lineHeight: '12px',
|
||||
letterSpacing: '0.2px',
|
||||
}),
|
||||
multiValueRemove: (baseStyles: CSSProperties) => ({
|
||||
multiValueRemove: (baseStyles) => ({
|
||||
...baseStyles,
|
||||
borderRadius: '50%',
|
||||
background: 'rgba(var(--center-channel-color-rgb), 0.32)',
|
||||
@@ -69,7 +70,7 @@ const styles = {
|
||||
color: 'white',
|
||||
},
|
||||
}),
|
||||
};
|
||||
} satisfies StylesConfig<SelectTextInputOption, true>;
|
||||
|
||||
const SelectTextInput = ({placeholder, value, handleNewSelection, onChange, id, isClearable, description}: Props) => {
|
||||
const [inputValue, setInputValue] = React.useState('');
|
||||
|
||||
@@ -3,10 +3,9 @@
|
||||
|
||||
import classNames from 'classnames';
|
||||
import React, {useCallback, useRef, useState} from 'react';
|
||||
import type {CSSProperties} from 'react';
|
||||
import {useIntl} from 'react-intl';
|
||||
import ReactSelect, {components} from 'react-select';
|
||||
import type {Props as SelectProps, ActionMeta} from 'react-select';
|
||||
import type {Props as SelectProps, ActionMeta, StylesConfig} from 'react-select';
|
||||
|
||||
import InputError from 'components/input_error';
|
||||
import type {CustomMessageInputType} from 'components/widgets/inputs/input/input';
|
||||
@@ -29,33 +28,35 @@ type Props<T extends ValueType> = Omit<SelectProps<T>, 'onChange'> & {
|
||||
onChange: (value: T, action: ActionMeta<T>) => void;
|
||||
testId?: string;
|
||||
required?: boolean;
|
||||
addon?: React.ReactNode;
|
||||
textPrefix?: React.ReactNode;
|
||||
};
|
||||
|
||||
const baseStyles = {
|
||||
input: (provided: CSSProperties) => ({
|
||||
input: (provided) => ({
|
||||
...provided,
|
||||
color: 'var(--center-channel-color)',
|
||||
}),
|
||||
control: (provided: CSSProperties) => ({
|
||||
control: (provided) => ({
|
||||
...provided,
|
||||
border: 'none',
|
||||
boxShadow: 'none',
|
||||
padding: '0 2px',
|
||||
cursor: 'pointer',
|
||||
}),
|
||||
indicatorSeparator: (provided: CSSProperties) => ({
|
||||
indicatorSeparator: (provided) => ({
|
||||
...provided,
|
||||
display: 'none',
|
||||
}),
|
||||
menu: (provided: CSSProperties) => ({
|
||||
menu: (provided) => ({
|
||||
...provided,
|
||||
zIndex: 100,
|
||||
}),
|
||||
menuPortal: (provided: CSSProperties) => ({
|
||||
menuPortal: (provided) => ({
|
||||
...provided,
|
||||
zIndex: 100,
|
||||
}),
|
||||
};
|
||||
} satisfies StylesConfig;
|
||||
|
||||
const IndicatorsContainer = (props: any) => {
|
||||
return (
|
||||
@@ -89,11 +90,11 @@ const Option = (props: any) => {
|
||||
};
|
||||
|
||||
const DropdownInput = <T extends ValueType>(props: Props<T>) => {
|
||||
const {value, placeholder, className, addon, name, textPrefix, legend, onChange, styles, options, error, testId, required, ...otherProps} = props;
|
||||
const {value, placeholder, className, addon, name, textPrefix, legend, onChange, styles, options, error, testId, required, ...otherProps} = props; // types are not inferred correctly for `props` in react-select version v5.
|
||||
|
||||
const [focused, setFocused] = useState(false);
|
||||
|
||||
const onInputFocus = (event: React.FocusEvent<HTMLElement>) => {
|
||||
const onInputFocus = (event: React.FocusEvent<HTMLInputElement>) => {
|
||||
const {onFocus} = props;
|
||||
|
||||
setFocused(true);
|
||||
@@ -122,7 +123,7 @@ const DropdownInput = <T extends ValueType>(props: Props<T>) => {
|
||||
setCustomInputLabel({type: ItemStatus.ERROR, value: validationErrorMsg});
|
||||
}, [required, formatMessage]);
|
||||
|
||||
const onInputBlur = useCallback((event: React.FocusEvent<HTMLElement>) => {
|
||||
const onInputBlur = useCallback((event: React.FocusEvent<HTMLInputElement>) => {
|
||||
setFocused(false);
|
||||
validateInput();
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ import React, {useEffect, useRef} from 'react';
|
||||
import {useIntl} from 'react-intl';
|
||||
import {useSelector} from 'react-redux';
|
||||
import {components} from 'react-select';
|
||||
import type {IndicatorProps, OptionProps, SingleValueProps, ValueType, OptionTypeBase} from 'react-select';
|
||||
import type {OptionProps, SingleValueProps, OnChangeValue, DropdownIndicatorProps, OptionsOrGroups, GroupBase} from 'react-select';
|
||||
import AsyncSelect from 'react-select/async';
|
||||
|
||||
import {
|
||||
@@ -46,11 +46,6 @@ export type ChannelOption = {
|
||||
details: ChannelTypeFromProvider;
|
||||
}
|
||||
|
||||
type GroupedOption = {
|
||||
label: React.ReactNode;
|
||||
options: ChannelOption[];
|
||||
}
|
||||
|
||||
export const makeSelectedChannelOption = (channel: Channel): ChannelOption => ({
|
||||
label: channel.display_name || channel.name,
|
||||
value: channel.id,
|
||||
@@ -210,7 +205,7 @@ const SingleValue = (props: SingleValueProps<ChannelOption>) => {
|
||||
);
|
||||
};
|
||||
|
||||
const DropdownIndicator = (props: IndicatorProps<ChannelOption>) => {
|
||||
const DropdownIndicator = (props: DropdownIndicatorProps<ChannelOption>) => {
|
||||
return (
|
||||
<components.DropdownIndicator {...props}>
|
||||
<ChevronDownIcon
|
||||
@@ -221,8 +216,8 @@ const DropdownIndicator = (props: IndicatorProps<ChannelOption>) => {
|
||||
);
|
||||
};
|
||||
|
||||
type Props<O extends OptionTypeBase> = {
|
||||
onSelect: (channel: ValueType<O>) => void;
|
||||
type Props<O> = {
|
||||
onSelect: (channel: OnChangeValue<O, boolean>) => void;
|
||||
currentBodyHeight: number;
|
||||
value?: O;
|
||||
validChannelTypes?: string[];
|
||||
@@ -241,7 +236,7 @@ function ForwardPostChannelSelect({onSelect, value, currentBodyHeight, validChan
|
||||
const isValidChannelType = (channel: Channel) => validChannelTypes.includes(channel.type) && !channel.delete_at;
|
||||
|
||||
const getDefaultResults = () => {
|
||||
let options: GroupedOption[] = [];
|
||||
let options: OptionsOrGroups<ChannelOption, GroupBase<ChannelOption>> = [];
|
||||
|
||||
const handleDefaultResults = (res: ProviderResult<any>) => {
|
||||
options = [
|
||||
@@ -259,7 +254,7 @@ function ForwardPostChannelSelect({onSelect, value, currentBodyHeight, validChan
|
||||
return options;
|
||||
};
|
||||
|
||||
const defaultOptions = useRef<GroupedOption[]>(getDefaultResults());
|
||||
const defaultOptions = useRef<OptionsOrGroups<ChannelOption, GroupBase<ChannelOption>>>(getDefaultResults());
|
||||
|
||||
const handleInputChange = (inputValue: string) => {
|
||||
return new Promise<ChannelOption[]>((resolve) => {
|
||||
@@ -299,7 +294,6 @@ function ForwardPostChannelSelect({onSelect, value, currentBodyHeight, validChan
|
||||
defaultOptions={defaultOptions.current}
|
||||
components={{DropdownIndicator, Option, SingleValue}}
|
||||
styles={baseStyles}
|
||||
legend='Forward to'
|
||||
placeholder='Select channel or people'
|
||||
className='forward-post__select'
|
||||
data-testid='forward-post-select'
|
||||
|
||||
@@ -1,30 +1,24 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import type * as CSS from 'csstype';
|
||||
import type {CSSProperties} from 'react';
|
||||
import type {ControlProps} from 'react-select';
|
||||
import type {StylesConfig} from 'react-select';
|
||||
|
||||
import type {ChannelOption} from './forward_post_channel_select';
|
||||
|
||||
type Pseudos = CSS.Pseudos | '::-webkit-scrollbar' | '::-webkit-scrollbar-track' | '::-webkit-scrollbar-thumb';
|
||||
|
||||
type CSSPropertiesWithPseudos = CSSProperties & { [P in Pseudos]?: CSS.Properties };
|
||||
|
||||
const menuMargin = 4;
|
||||
const selectHeight = 40;
|
||||
|
||||
const getBaseStyles = (bodyHeight: number) => {
|
||||
const getBaseStyles = (bodyHeight: number): StylesConfig<ChannelOption, boolean> => {
|
||||
const minMenuHeight = bodyHeight - selectHeight - menuMargin;
|
||||
|
||||
return ({
|
||||
input: (provided: CSSProperties): CSSPropertiesWithPseudos => ({
|
||||
input: (provided) => ({
|
||||
...provided,
|
||||
padding: 0,
|
||||
margin: 0,
|
||||
color: 'var(--center-channel-color)',
|
||||
}),
|
||||
placeholder: (provided: CSSProperties): CSSPropertiesWithPseudos => ({
|
||||
placeholder: (provided) => ({
|
||||
...provided,
|
||||
margin: 0,
|
||||
color: 'rgba(var(--center-channel-color-rgb), 0.75)',
|
||||
@@ -32,9 +26,7 @@ const getBaseStyles = (bodyHeight: number) => {
|
||||
lineHeight: '20px',
|
||||
}),
|
||||
|
||||
// disabling this rule here since otherwise tsc will complain about it in the props
|
||||
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||
control: (provided: CSSProperties, state: ControlProps<{}>): CSSPropertiesWithPseudos => {
|
||||
control: (provided, state) => {
|
||||
const focusShadow = 'inset 0 0 0 2px var(--button-bg)';
|
||||
|
||||
return ({
|
||||
@@ -53,31 +45,31 @@ const getBaseStyles = (bodyHeight: number) => {
|
||||
},
|
||||
});
|
||||
},
|
||||
indicatorSeparator: (): CSSPropertiesWithPseudos => ({
|
||||
indicatorSeparator: () => ({
|
||||
display: 'none',
|
||||
}),
|
||||
indicatorsContainer: (provided: CSSProperties): CSSPropertiesWithPseudos => ({
|
||||
indicatorsContainer: (provided) => ({
|
||||
...provided,
|
||||
padding: '2px',
|
||||
}),
|
||||
dropdownIndicator: (provided: CSSProperties, state: ControlProps<ChannelOption>): CSSPropertiesWithPseudos => ({
|
||||
dropdownIndicator: (provided, state) => ({
|
||||
...provided,
|
||||
transform: state.isFocused ? 'rotate(180deg)' : 'rotate(0)',
|
||||
transition: 'transform 250ms ease-in-out',
|
||||
}),
|
||||
valueContainer: (provided: CSSProperties): CSSPropertiesWithPseudos => ({
|
||||
valueContainer: (provided) => ({
|
||||
...provided,
|
||||
overflow: 'visible',
|
||||
padding: '0 16px 0 0',
|
||||
margin: 0,
|
||||
}),
|
||||
menu: (provided: CSSProperties): CSSPropertiesWithPseudos => ({
|
||||
menu: (provided) => ({
|
||||
...provided,
|
||||
padding: 0,
|
||||
margin: `${menuMargin}px 0 0 0`,
|
||||
zIndex: 10,
|
||||
}),
|
||||
menuList: (provided: CSSProperties): CSSPropertiesWithPseudos => ({
|
||||
menuList: (provided) => ({
|
||||
...provided,
|
||||
padding: 0,
|
||||
backgroundColor: 'var(--center-channel-bg)',
|
||||
@@ -110,7 +102,7 @@ const getBaseStyles = (bodyHeight: number) => {
|
||||
borderRadius: '9999px',
|
||||
},
|
||||
}),
|
||||
groupHeading: (provided: CSSProperties): CSSPropertiesWithPseudos => ({
|
||||
groupHeading: (provided) => ({
|
||||
...provided,
|
||||
cursor: 'default',
|
||||
position: 'relative',
|
||||
@@ -126,19 +118,19 @@ const getBaseStyles = (bodyHeight: number) => {
|
||||
fontWeight: 600,
|
||||
textTransform: 'uppercase',
|
||||
}),
|
||||
singleValue: (provided: CSSProperties): CSSPropertiesWithPseudos => ({
|
||||
singleValue: (provided) => ({
|
||||
...provided,
|
||||
maxWidth: 'calc(100% - 10px)',
|
||||
width: '100%',
|
||||
overflow: 'visible',
|
||||
}),
|
||||
option: (provided: CSSProperties, state: ControlProps<ChannelOption>): CSSPropertiesWithPseudos => ({
|
||||
option: (provided, state) => ({
|
||||
...provided,
|
||||
cursor: 'pointer',
|
||||
padding: '8px 20px',
|
||||
backgroundColor: state.isFocused ? 'rgba(var(--center-channel-color-rgb), 0.08)' : 'transparent',
|
||||
}),
|
||||
menuPortalTarget: (provided: CSSProperties): CSSPropertiesWithPseudos => ({
|
||||
menuPortal: (provided) => ({
|
||||
...provided,
|
||||
zIndex: 10,
|
||||
}),
|
||||
|
||||
@@ -5,7 +5,7 @@ import classNames from 'classnames';
|
||||
import React, {useCallback, useRef, useState, useMemo} from 'react';
|
||||
import {FormattedList, FormattedMessage, useIntl} from 'react-intl';
|
||||
import {useDispatch, useSelector} from 'react-redux';
|
||||
import type {ValueType} from 'react-select';
|
||||
import type {OnChangeValue} from 'react-select';
|
||||
|
||||
import {GenericModal} from '@mattermost/components';
|
||||
import type {Post, PostPreviewMetadata} from '@mattermost/types/posts';
|
||||
@@ -108,7 +108,7 @@ const ForwardPostModal = ({onExited, post}: Props) => {
|
||||
}, [onExited]);
|
||||
|
||||
const handleChannelSelect = useCallback(
|
||||
(channel: ValueType<ChannelOption>) => {
|
||||
(channel: OnChangeValue<ChannelOption, boolean>) => {
|
||||
if (Array.isArray(channel)) {
|
||||
setSelectedChannel(channel[0]);
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ import classNames from 'classnames';
|
||||
import React, {useCallback, useMemo, useRef, useState} from 'react';
|
||||
import {useIntl} from 'react-intl';
|
||||
import {useSelector} from 'react-redux';
|
||||
import type {ValueType} from 'react-select';
|
||||
import type {OnChangeValue} from 'react-select';
|
||||
|
||||
import type {ClientError} from '@mattermost/client';
|
||||
import {GenericModal} from '@mattermost/components';
|
||||
@@ -87,7 +87,7 @@ const MoveThreadModal = ({onExited, post, actions}: Props) => {
|
||||
onExited?.();
|
||||
}, [onExited]);
|
||||
|
||||
const handleChannelSelect = useCallback((channel: ValueType<ChannelOption>) => {
|
||||
const handleChannelSelect = useCallback((channel: OnChangeValue<ChannelOption, boolean>) => {
|
||||
if (Array.isArray(channel)) {
|
||||
setSelectedChannel(channel[0]);
|
||||
return;
|
||||
|
||||
@@ -11,7 +11,7 @@ exports[`components/multiselect/multiselect MultiSelectList should match snapsho
|
||||
<div
|
||||
className="multi-select__container react-select"
|
||||
>
|
||||
<StateManager
|
||||
<ForwardRef
|
||||
className=""
|
||||
classNamePrefix="react-select-auto react-select"
|
||||
components={
|
||||
@@ -22,9 +22,6 @@ exports[`components/multiselect/multiselect MultiSelectList should match snapsho
|
||||
"MultiValueRemove": [Function],
|
||||
}
|
||||
}
|
||||
defaultInputValue=""
|
||||
defaultMenuIsOpen={false}
|
||||
defaultValue={null}
|
||||
getOptionLabel={[Function]}
|
||||
getOptionValue={[Function]}
|
||||
id="selectItems"
|
||||
@@ -198,7 +195,7 @@ exports[`components/multiselect/multiselect should match snapshot 1`] = `
|
||||
<div
|
||||
className="multi-select__container react-select"
|
||||
>
|
||||
<StateManager
|
||||
<ForwardRef
|
||||
className=""
|
||||
classNamePrefix="react-select-auto react-select"
|
||||
components={
|
||||
@@ -209,9 +206,6 @@ exports[`components/multiselect/multiselect should match snapshot 1`] = `
|
||||
"MultiValueRemove": [Function],
|
||||
}
|
||||
}
|
||||
defaultInputValue=""
|
||||
defaultMenuIsOpen={false}
|
||||
defaultValue={null}
|
||||
getOptionLabel={[Function]}
|
||||
getOptionValue={[Function]}
|
||||
id="selectItems"
|
||||
@@ -376,7 +370,7 @@ exports[`components/multiselect/multiselect should match snapshot for page 2 1`]
|
||||
<div
|
||||
className="multi-select__container react-select"
|
||||
>
|
||||
<StateManager
|
||||
<ForwardRef
|
||||
className=""
|
||||
classNamePrefix="react-select-auto react-select"
|
||||
components={
|
||||
@@ -387,9 +381,6 @@ exports[`components/multiselect/multiselect should match snapshot for page 2 1`]
|
||||
"MultiValueRemove": [Function],
|
||||
}
|
||||
}
|
||||
defaultInputValue=""
|
||||
defaultMenuIsOpen={false}
|
||||
defaultValue={null}
|
||||
getOptionLabel={[Function]}
|
||||
getOptionValue={[Function]}
|
||||
id="selectItems"
|
||||
|
||||
@@ -3,12 +3,11 @@
|
||||
|
||||
import classNames from 'classnames';
|
||||
import React from 'react';
|
||||
import type {ReactNode} from 'react';
|
||||
import type {ComponentProps, ReactNode} from 'react';
|
||||
import type {IntlShape, MessageDescriptor} from 'react-intl';
|
||||
import {FormattedMessage} from 'react-intl';
|
||||
import ReactSelect, {components} from 'react-select';
|
||||
import type {getOptionValue} from 'react-select/src/builtins';
|
||||
import type {InputActionMeta} from 'react-select/src/types';
|
||||
import type {GetOptionValue, InputActionMeta, SelectInstance} from 'react-select';
|
||||
|
||||
import SaveButton from 'components/save_button';
|
||||
import CloseCircleSolidIcon from 'components/widgets/icons/close_circle_solid_icon';
|
||||
@@ -30,7 +29,7 @@ export type Value = {
|
||||
};
|
||||
|
||||
export type Props<T extends Value> = {
|
||||
ariaLabelRenderer: getOptionValue<T>;
|
||||
ariaLabelRenderer: GetOptionValue<T>;
|
||||
backButtonClick?: () => void;
|
||||
backButtonClass?: string;
|
||||
backButtonText?: string | MessageDescriptor;
|
||||
@@ -80,7 +79,7 @@ const KeyCodes = Constants.KeyCodes;
|
||||
|
||||
export class MultiSelect<T extends Value> extends React.PureComponent<Props<T>, State> {
|
||||
private listRef = React.createRef<MultiSelectList<T>>();
|
||||
private reactSelectRef = React.createRef<ReactSelect>();
|
||||
private reactSelectRef = React.createRef<SelectInstance<T>>();
|
||||
private selected: T | null = null;
|
||||
|
||||
public static defaultProps = {
|
||||
@@ -102,7 +101,7 @@ export class MultiSelect<T extends Value> extends React.PureComponent<Props<T>,
|
||||
}
|
||||
|
||||
public componentDidMount() {
|
||||
const inputRef: unknown = this.reactSelectRef.current && this.reactSelectRef.current.select.inputRef;
|
||||
const inputRef: unknown = this.reactSelectRef.current && this.reactSelectRef.current.inputRef;
|
||||
|
||||
document.addEventListener<'keydown'>('keydown', this.handleEnterPress);
|
||||
if (inputRef && typeof (inputRef as HTMLElement).addEventListener === 'function') {
|
||||
@@ -119,7 +118,7 @@ export class MultiSelect<T extends Value> extends React.PureComponent<Props<T>,
|
||||
}
|
||||
|
||||
public componentWillUnmount() {
|
||||
const inputRef: unknown = this.reactSelectRef.current && this.reactSelectRef.current.select.inputRef;
|
||||
const inputRef: unknown = this.reactSelectRef.current && this.reactSelectRef.current.inputRef;
|
||||
|
||||
if (inputRef && typeof (inputRef as HTMLElement).addEventListener === 'function') {
|
||||
(inputRef as HTMLElement).removeEventListener(A11yCustomEventTypes.ACTIVATE, this.handleA11yActivateEvent);
|
||||
@@ -185,7 +184,7 @@ export class MultiSelect<T extends Value> extends React.PureComponent<Props<T>,
|
||||
this.selected = null;
|
||||
|
||||
if (this.reactSelectRef.current) {
|
||||
this.reactSelectRef.current.select.handleInputChange(
|
||||
this.reactSelectRef.current.handleInputChange(
|
||||
{currentTarget: {value: ''}} as React.KeyboardEvent<HTMLInputElement>,
|
||||
);
|
||||
this.reactSelectRef.current.focus();
|
||||
@@ -249,7 +248,7 @@ export class MultiSelect<T extends Value> extends React.PureComponent<Props<T>,
|
||||
this.props.handleSubmit();
|
||||
};
|
||||
|
||||
private onChange: ReactSelect['onChange'] = (_, change) => {
|
||||
private onChange: ComponentProps<ReactSelect>['onChange'] = (_, change) => {
|
||||
if (change.action !== 'remove-value' && change.action !== 'pop-value') {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
import React from 'react';
|
||||
import {FormattedMessage} from 'react-intl';
|
||||
import type {getOptionValue} from 'react-select/src/builtins';
|
||||
import type {GetOptionValue} from 'react-select';
|
||||
|
||||
import LoadingScreen from 'components/loading_screen';
|
||||
|
||||
@@ -13,7 +13,7 @@ import {cmdOrCtrlPressed} from 'utils/keyboard';
|
||||
import type {Value} from './multiselect';
|
||||
|
||||
export type Props<T extends Value> = {
|
||||
ariaLabelRenderer: getOptionValue<T>;
|
||||
ariaLabelRenderer: GetOptionValue<T>;
|
||||
loading?: boolean;
|
||||
onAdd: (value: T) => void;
|
||||
onPageChange?: (newPage: number, currentPage: number) => void;
|
||||
|
||||
@@ -114,68 +114,81 @@ exports[`InviteMembers component should match snapshot when it is cloud 1`] = `
|
||||
class="PreparingWorkspacePageBody"
|
||||
>
|
||||
<div
|
||||
class="UsersEmailsInput empty no-selections css-2b097c-container"
|
||||
class="UsersEmailsInput empty no-selections css-b62m3t-container"
|
||||
>
|
||||
<span
|
||||
aria-live="assertive"
|
||||
class="css-1laao21-a11yText"
|
||||
class="css-1f43avz-a11yText-A11yText"
|
||||
id="react-select-2-live-region"
|
||||
/>
|
||||
<span
|
||||
aria-atomic="false"
|
||||
aria-live="polite"
|
||||
aria-relevant="additions text"
|
||||
class="css-1f43avz-a11yText-A11yText"
|
||||
role="log"
|
||||
>
|
||||
<p
|
||||
id="aria-selection-event"
|
||||
<span
|
||||
id="aria-selection"
|
||||
/>
|
||||
<span
|
||||
id="aria-focused"
|
||||
/>
|
||||
<span
|
||||
id="aria-results"
|
||||
/>
|
||||
<span
|
||||
id="aria-guidance"
|
||||
>
|
||||
|
||||
|
||||
</p>
|
||||
<p
|
||||
id="aria-context"
|
||||
>
|
||||
|
||||
0 results available. 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.
|
||||
</p>
|
||||
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.
|
||||
</span>
|
||||
</span>
|
||||
<div
|
||||
class="users-emails-input__control users-emails-input__control--is-focused users-emails-input__control--menu-is-open css-1pahdxg-control"
|
||||
class="users-emails-input__control users-emails-input__control--is-focused users-emails-input__control--menu-is-open css-t3ipsp-control"
|
||||
>
|
||||
<div
|
||||
class="users-emails-input__value-container users-emails-input__value-container--is-multi css-1hwfws3"
|
||||
class="users-emails-input__value-container users-emails-input__value-container--is-multi css-hlgwow"
|
||||
>
|
||||
<div
|
||||
class="users-emails-input__placeholder css-1lxtzh0-placeholder"
|
||||
class="users-emails-input__placeholder css-10imb99-placeholder"
|
||||
id="react-select-2-placeholder"
|
||||
>
|
||||
Enter email addresses
|
||||
</div>
|
||||
<div
|
||||
class="css-gftnqw-Input"
|
||||
class="users-emails-input__input-container css-11wvis5"
|
||||
data-value=""
|
||||
>
|
||||
<div
|
||||
<input
|
||||
aria-activedescendant=""
|
||||
aria-autocomplete="list"
|
||||
aria-controls="react-select-2-listbox"
|
||||
aria-describedby="react-select-2-placeholder"
|
||||
aria-expanded="true"
|
||||
aria-haspopup="true"
|
||||
aria-label="Invite People"
|
||||
autocapitalize="none"
|
||||
autocomplete="off"
|
||||
autocorrect="off"
|
||||
class="users-emails-input__input"
|
||||
style="display: inline-block;"
|
||||
>
|
||||
<input
|
||||
aria-autocomplete="list"
|
||||
aria-label="Invite People"
|
||||
autocapitalize="none"
|
||||
autocomplete="off"
|
||||
autocorrect="off"
|
||||
id="react-select-2-input"
|
||||
spellcheck="false"
|
||||
style="box-sizing: content-box; width: 2px; border: 0px; opacity: 1; outline: 0; padding: 0px;"
|
||||
tabindex="0"
|
||||
type="text"
|
||||
value=""
|
||||
/>
|
||||
<div
|
||||
style="position: absolute; top: 0px; left: 0px; visibility: hidden; height: 0px; overflow: scroll; white-space: pre; font-family: -webkit-small-control; letter-spacing: normal; text-transform: none;"
|
||||
/>
|
||||
</div>
|
||||
id="react-select-2-input"
|
||||
role="combobox"
|
||||
spellcheck="false"
|
||||
style="opacity: 1; width: 100%; grid-area: 1 / 2; min-width: 2px; border: 0px; margin: 0px; outline: 0; padding: 0px;"
|
||||
tabindex="0"
|
||||
type="text"
|
||||
value=""
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="users-emails-input__menu css-26l3qy-menu"
|
||||
class="users-emails-input__menu css-1nmdiq5-menu"
|
||||
>
|
||||
<div
|
||||
class="users-emails-input__menu-list users-emails-input__menu-list--is-multi css-4ljt47-MenuList"
|
||||
aria-multiselectable="true"
|
||||
class="users-emails-input__menu-list users-emails-input__menu-list--is-multi css-qr46ko"
|
||||
id="react-select-2-listbox"
|
||||
role="listbox"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -161,53 +161,64 @@ Object {
|
||||
class="Input_wrapper"
|
||||
>
|
||||
<div
|
||||
class="Input company_size_dropdown css-2b097c-container"
|
||||
class="Input company_size_dropdown css-b62m3t-container"
|
||||
id="DropdownInput_company_size_dropdown"
|
||||
>
|
||||
<span
|
||||
class="css-1f43avz-a11yText-A11yText"
|
||||
id="react-select-2-live-region"
|
||||
/>
|
||||
<span
|
||||
aria-atomic="false"
|
||||
aria-live="polite"
|
||||
aria-relevant="additions text"
|
||||
class="css-1f43avz-a11yText-A11yText"
|
||||
role="log"
|
||||
/>
|
||||
<div
|
||||
class="DropdownInput__controlContainer"
|
||||
>
|
||||
<div
|
||||
class="DropDown__control css-1nr98fh-control"
|
||||
class="DropDown__control css-2vz60i-control"
|
||||
>
|
||||
<div
|
||||
class="DropDown__value-container css-1hwfws3"
|
||||
class="DropDown__value-container css-hlgwow"
|
||||
>
|
||||
<div
|
||||
class="DropDown__placeholder css-1wa3eu0-placeholder"
|
||||
class="DropDown__placeholder css-1jqq78o-placeholder"
|
||||
id="react-select-2-placeholder"
|
||||
>
|
||||
Company Size
|
||||
</div>
|
||||
<div
|
||||
class="css-1ed09z3-Input"
|
||||
class="DropDown__input-container css-19yuyn7"
|
||||
data-value=""
|
||||
>
|
||||
<div
|
||||
<input
|
||||
aria-activedescendant=""
|
||||
aria-autocomplete="list"
|
||||
aria-describedby="react-select-2-placeholder"
|
||||
aria-expanded="false"
|
||||
aria-haspopup="true"
|
||||
autocapitalize="none"
|
||||
autocomplete="off"
|
||||
autocorrect="off"
|
||||
class="DropDown__input"
|
||||
style="display: inline-block;"
|
||||
>
|
||||
<input
|
||||
aria-autocomplete="list"
|
||||
autocapitalize="none"
|
||||
autocomplete="off"
|
||||
autocorrect="off"
|
||||
id="react-select-2-input"
|
||||
spellcheck="false"
|
||||
style="box-sizing: content-box; width: 2px; border: 0px; opacity: 1; outline: 0; padding: 0px;"
|
||||
tabindex="0"
|
||||
type="text"
|
||||
value=""
|
||||
/>
|
||||
<div
|
||||
style="position: absolute; top: 0px; left: 0px; visibility: hidden; height: 0px; overflow: scroll; white-space: pre; font-family: -webkit-small-control; letter-spacing: normal; text-transform: none;"
|
||||
/>
|
||||
</div>
|
||||
id="react-select-2-input"
|
||||
role="combobox"
|
||||
spellcheck="false"
|
||||
style="opacity: 1; width: 100%; grid-area: 1 / 2; min-width: 2px; border: 0px; margin: 0px; outline: 0; padding: 0px;"
|
||||
tabindex="0"
|
||||
type="text"
|
||||
value=""
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="DropdownInput__indicatorsContainer"
|
||||
>
|
||||
<div
|
||||
class="DropDown__indicators css-1hb7zxy-IndicatorsContainer"
|
||||
class="DropDown__indicators css-1wy0on6"
|
||||
>
|
||||
<i
|
||||
class="icon icon-chevron-down"
|
||||
@@ -237,53 +248,64 @@ Object {
|
||||
class="Input_wrapper"
|
||||
>
|
||||
<div
|
||||
class="Input css-2b097c-container"
|
||||
class="Input css-b62m3t-container"
|
||||
id="DropdownInput_country_dropdown"
|
||||
>
|
||||
<span
|
||||
class="css-1f43avz-a11yText-A11yText"
|
||||
id="react-select-3-live-region"
|
||||
/>
|
||||
<span
|
||||
aria-atomic="false"
|
||||
aria-live="polite"
|
||||
aria-relevant="additions text"
|
||||
class="css-1f43avz-a11yText-A11yText"
|
||||
role="log"
|
||||
/>
|
||||
<div
|
||||
class="DropdownInput__controlContainer"
|
||||
>
|
||||
<div
|
||||
class="DropDown__control css-1nr98fh-control"
|
||||
class="DropDown__control css-2vz60i-control"
|
||||
>
|
||||
<div
|
||||
class="DropDown__value-container css-1hwfws3"
|
||||
class="DropDown__value-container css-hlgwow"
|
||||
>
|
||||
<div
|
||||
class="DropDown__placeholder css-1wa3eu0-placeholder"
|
||||
class="DropDown__placeholder css-1jqq78o-placeholder"
|
||||
id="react-select-3-placeholder"
|
||||
>
|
||||
Country/Region
|
||||
</div>
|
||||
<div
|
||||
class="css-1ed09z3-Input"
|
||||
class="DropDown__input-container css-19yuyn7"
|
||||
data-value=""
|
||||
>
|
||||
<div
|
||||
<input
|
||||
aria-activedescendant=""
|
||||
aria-autocomplete="list"
|
||||
aria-describedby="react-select-3-placeholder"
|
||||
aria-expanded="false"
|
||||
aria-haspopup="true"
|
||||
autocapitalize="none"
|
||||
autocomplete="off"
|
||||
autocorrect="off"
|
||||
class="DropDown__input"
|
||||
style="display: inline-block;"
|
||||
>
|
||||
<input
|
||||
aria-autocomplete="list"
|
||||
autocapitalize="none"
|
||||
autocomplete="off"
|
||||
autocorrect="off"
|
||||
id="react-select-3-input"
|
||||
spellcheck="false"
|
||||
style="box-sizing: content-box; width: 2px; border: 0px; opacity: 1; outline: 0; padding: 0px;"
|
||||
tabindex="0"
|
||||
type="text"
|
||||
value=""
|
||||
/>
|
||||
<div
|
||||
style="position: absolute; top: 0px; left: 0px; visibility: hidden; height: 0px; overflow: scroll; white-space: pre; font-family: -webkit-small-control; letter-spacing: normal; text-transform: none;"
|
||||
/>
|
||||
</div>
|
||||
id="react-select-3-input"
|
||||
role="combobox"
|
||||
spellcheck="false"
|
||||
style="opacity: 1; width: 100%; grid-area: 1 / 2; min-width: 2px; border: 0px; margin: 0px; outline: 0; padding: 0px;"
|
||||
tabindex="0"
|
||||
type="text"
|
||||
value=""
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="DropdownInput__indicatorsContainer"
|
||||
>
|
||||
<div
|
||||
class="DropDown__indicators css-1hb7zxy-IndicatorsContainer"
|
||||
class="DropDown__indicators css-1wy0on6"
|
||||
>
|
||||
<i
|
||||
class="icon icon-chevron-down"
|
||||
|
||||
@@ -323,7 +323,7 @@ function StartTrialFormModal(props: Props): JSX.Element | null {
|
||||
setOrgSize(e.value as OrgSize);
|
||||
}}
|
||||
value={getOrgSizeDropdownValue()}
|
||||
options={Object.entries(OrgSize).map(([value, label]) => ({value, label}))}
|
||||
options={Object.entries(OrgSize).map(([value, label]) => ({value, label})) as any} // options type is not correctly set in DropdownInput component.
|
||||
legend={formatMessage({id: 'start_trial_form.company_size', defaultMessage: 'Company Size'})}
|
||||
placeholder={formatMessage({id: 'start_trial_form.company_size', defaultMessage: 'Company Size'})}
|
||||
name='company_size_dropdown'
|
||||
|
||||
@@ -100,7 +100,7 @@ describe('components/TeamSettings', () => {
|
||||
test('should call patchTeam on handleAllowedDomainsSubmit', async () => {
|
||||
const props = {...defaultProps, team: TestHelper.getTeamMock({allowed_domains: 'test.com'})};
|
||||
renderWithContext(<AccessTab {...props}/>);
|
||||
const allowedDomainsInput = screen.getAllByRole('textbox')[0];
|
||||
const allowedDomainsInput = screen.getAllByRole('combobox')[0];
|
||||
const newDomain = 'best.com';
|
||||
await act(async () => {
|
||||
await allowedDomainsInput.focus();
|
||||
|
||||
@@ -5,7 +5,7 @@ import React from 'react';
|
||||
import {FormattedMessage, injectIntl} from 'react-intl';
|
||||
import type {IntlShape} from 'react-intl';
|
||||
import ReactSelect from 'react-select';
|
||||
import type {ValueType} from 'react-select';
|
||||
import type {StylesConfig, OnChangeValue, AriaOnFocus, AriaOnChange} from 'react-select';
|
||||
|
||||
import type {UserProfile} from '@mattermost/types/users';
|
||||
|
||||
@@ -101,7 +101,7 @@ export class ManageLanguage extends React.PureComponent<Props, State> {
|
||||
}
|
||||
};
|
||||
|
||||
setLanguage = (selectedOption: ValueType<SelectedOption>) => {
|
||||
setLanguage = (selectedOption: OnChangeValue<SelectedOption, boolean>) => {
|
||||
if (selectedOption && 'value' in selectedOption) {
|
||||
this.setState({
|
||||
locale: selectedOption.value,
|
||||
@@ -184,11 +184,20 @@ export class ManageLanguage extends React.PureComponent<Props, State> {
|
||||
});
|
||||
|
||||
const reactStyles = {
|
||||
menuPortal: (provided: React.CSSProperties) => ({
|
||||
menuPortal: (provided) => ({
|
||||
...provided,
|
||||
zIndex: 9999,
|
||||
}),
|
||||
} satisfies StylesConfig<SelectedOption, boolean>;
|
||||
|
||||
const onFocusMessage: AriaOnFocus<SelectedOption> = ({focused}) => {
|
||||
return `option ${focused.label} focused`;
|
||||
};
|
||||
|
||||
const onChangeMessage: AriaOnChange<SelectedOption, boolean> = (option) => {
|
||||
return `option ${option.label} selected`;
|
||||
};
|
||||
|
||||
const interfaceLanguageLabelAria = intl.formatMessage({id: 'user.settings.languages.dropdown.arialabel', defaultMessage: 'Dropdown selector to change the interface language'});
|
||||
|
||||
const input = (
|
||||
@@ -212,18 +221,23 @@ export class ManageLanguage extends React.PureComponent<Props, State> {
|
||||
<ReactSelect
|
||||
className='react-select react-select-top'
|
||||
classNamePrefix='react-select'
|
||||
ariaLiveMessages={{
|
||||
onFocus: onFocusMessage,
|
||||
onChange: onChangeMessage,
|
||||
}}
|
||||
id='displayLanguage'
|
||||
menuIsOpen={this.state.openMenu}
|
||||
menuPortalTarget={document.body}
|
||||
styles={reactStyles}
|
||||
options={options}
|
||||
clearable={false}
|
||||
isClearable={false}
|
||||
onChange={this.setLanguage}
|
||||
onKeyDown={this.handleKeyDown}
|
||||
value={this.state.selectedOption}
|
||||
onMenuClose={this.handleMenuClose}
|
||||
onMenuOpen={this.handleMenuOpen}
|
||||
aria-labelledby='changeInterfaceLanguageLabel'
|
||||
aria-live='assertive'
|
||||
/>
|
||||
{serverError}
|
||||
</div>
|
||||
@@ -264,6 +278,7 @@ export class ManageLanguage extends React.PureComponent<Props, State> {
|
||||
saving={this.state.isSaving}
|
||||
inputs={[input]}
|
||||
updateSection={this.props.updateSection}
|
||||
disableEnterSubmit={true}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
import React from 'react';
|
||||
import {FormattedMessage} from 'react-intl';
|
||||
import ReactSelect from 'react-select';
|
||||
import type {ValueType} from 'react-select';
|
||||
import type {OnChangeValue, StylesConfig} from 'react-select';
|
||||
import type {Timezone} from 'timezones.json';
|
||||
|
||||
import type {UserProfile} from '@mattermost/types/users';
|
||||
@@ -60,7 +60,7 @@ export default class ManageTimezones extends React.PureComponent<Props, State> {
|
||||
};
|
||||
}
|
||||
|
||||
onChange = (selectedOption: ValueType<SelectedOption>) => {
|
||||
onChange = (selectedOption: OnChangeValue<SelectedOption, boolean>) => {
|
||||
if (selectedOption && 'value' in selectedOption) {
|
||||
this.setState({
|
||||
manualTimezone: selectedOption.value,
|
||||
@@ -198,12 +198,12 @@ export default class ManageTimezones extends React.PureComponent<Props, State> {
|
||||
|
||||
const reactStyles = {
|
||||
|
||||
menuPortal: (provided: React.CSSProperties) => ({
|
||||
menuPortal: (provided) => ({
|
||||
...provided,
|
||||
zIndex: 9999,
|
||||
}),
|
||||
|
||||
};
|
||||
} satisfies StylesConfig<SelectedOption, boolean>;
|
||||
|
||||
const noTimezonesFromServer = timezones.length === 0;
|
||||
const automaticTimezoneInput = (
|
||||
@@ -240,7 +240,7 @@ export default class ManageTimezones extends React.PureComponent<Props, State> {
|
||||
menuPortalTarget={document.body}
|
||||
styles={reactStyles}
|
||||
options={timeOptions}
|
||||
clearable={false}
|
||||
isClearable={false}
|
||||
onChange={this.onChange}
|
||||
value={this.state.selectedOption}
|
||||
aria-labelledby='changeInterfaceTimezoneLabel'
|
||||
@@ -277,6 +277,7 @@ export default class ManageTimezones extends React.PureComponent<Props, State> {
|
||||
saving={this.state.isSaving}
|
||||
inputs={inputs}
|
||||
updateSection={this.props.updateSection}
|
||||
disableEnterSubmit={true}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -95,37 +95,55 @@ exports[`DesktopNotificationSettings should match snapshot, on max setting 1`] =
|
||||
Trigger mobile notifications when I am:
|
||||
</label>
|
||||
<div
|
||||
class="react-select singleSelect css-2b097c-container"
|
||||
class="react-select singleSelect css-b62m3t-container"
|
||||
>
|
||||
<span
|
||||
class="css-1f43avz-a11yText-A11yText"
|
||||
id="react-select-2-live-region"
|
||||
/>
|
||||
<span
|
||||
aria-atomic="false"
|
||||
aria-live="polite"
|
||||
aria-relevant="additions text"
|
||||
class="css-1f43avz-a11yText-A11yText"
|
||||
role="log"
|
||||
/>
|
||||
<div
|
||||
class="react-select__control css-yk16xz-control"
|
||||
class="react-select__control css-13cymwt-control"
|
||||
>
|
||||
<div
|
||||
class="react-select__value-container react-select__value-container--has-value css-1hwfws3"
|
||||
class="react-select__value-container react-select__value-container--has-value css-hlgwow"
|
||||
>
|
||||
<div
|
||||
class="react-select__single-value css-1uccc91-singleValue"
|
||||
class="react-select__single-value css-1dimb5e-singleValue"
|
||||
>
|
||||
Offline
|
||||
</div>
|
||||
<input
|
||||
class="css-62g3xt-dummyInput"
|
||||
aria-activedescendant=""
|
||||
aria-autocomplete="list"
|
||||
aria-expanded="false"
|
||||
aria-haspopup="true"
|
||||
aria-labelledby="pushMobileNotificationsLabel"
|
||||
aria-readonly="true"
|
||||
class="css-1s80ejz-dummyInput-DummyInput"
|
||||
id="pushMobileNotificationSelectInput"
|
||||
readonly=""
|
||||
inputmode="none"
|
||||
role="combobox"
|
||||
tabindex="0"
|
||||
value=""
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="react-select__indicators css-1hb7zxy-IndicatorsContainer"
|
||||
class="react-select__indicators css-1wy0on6"
|
||||
>
|
||||
<div
|
||||
aria-hidden="true"
|
||||
class="react-select__indicator react-select__dropdown-indicator css-tlfecz-indicatorContainer"
|
||||
class="react-select__indicator react-select__dropdown-indicator css-1xc3v61-indicatorContainer"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
class="css-6q0nyr-Svg"
|
||||
class="css-tj5bde-Svg"
|
||||
focusable="false"
|
||||
height="20"
|
||||
viewBox="0 0 20 20"
|
||||
@@ -289,37 +307,55 @@ exports[`DesktopNotificationSettings should not show desktop thread notification
|
||||
Trigger mobile notifications when I am:
|
||||
</label>
|
||||
<div
|
||||
class="react-select singleSelect css-2b097c-container"
|
||||
class="react-select singleSelect css-b62m3t-container"
|
||||
>
|
||||
<span
|
||||
class="css-1f43avz-a11yText-A11yText"
|
||||
id="react-select-3-live-region"
|
||||
/>
|
||||
<span
|
||||
aria-atomic="false"
|
||||
aria-live="polite"
|
||||
aria-relevant="additions text"
|
||||
class="css-1f43avz-a11yText-A11yText"
|
||||
role="log"
|
||||
/>
|
||||
<div
|
||||
class="react-select__control css-yk16xz-control"
|
||||
class="react-select__control css-13cymwt-control"
|
||||
>
|
||||
<div
|
||||
class="react-select__value-container react-select__value-container--has-value css-1hwfws3"
|
||||
class="react-select__value-container react-select__value-container--has-value css-hlgwow"
|
||||
>
|
||||
<div
|
||||
class="react-select__single-value css-1uccc91-singleValue"
|
||||
class="react-select__single-value css-1dimb5e-singleValue"
|
||||
>
|
||||
Offline
|
||||
</div>
|
||||
<input
|
||||
class="css-62g3xt-dummyInput"
|
||||
aria-activedescendant=""
|
||||
aria-autocomplete="list"
|
||||
aria-expanded="false"
|
||||
aria-haspopup="true"
|
||||
aria-labelledby="pushMobileNotificationsLabel"
|
||||
aria-readonly="true"
|
||||
class="css-1s80ejz-dummyInput-DummyInput"
|
||||
id="pushMobileNotificationSelectInput"
|
||||
readonly=""
|
||||
inputmode="none"
|
||||
role="combobox"
|
||||
tabindex="0"
|
||||
value=""
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="react-select__indicators css-1hb7zxy-IndicatorsContainer"
|
||||
class="react-select__indicators css-1wy0on6"
|
||||
>
|
||||
<div
|
||||
aria-hidden="true"
|
||||
class="react-select__indicator react-select__dropdown-indicator css-tlfecz-indicatorContainer"
|
||||
class="react-select__indicator react-select__dropdown-indicator css-1xc3v61-indicatorContainer"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
class="css-6q0nyr-Svg"
|
||||
class="css-tj5bde-Svg"
|
||||
focusable="false"
|
||||
height="20"
|
||||
viewBox="0 0 20 20"
|
||||
|
||||
@@ -5,7 +5,7 @@ import React, {Fragment, useCallback, useEffect, useMemo, useRef, memo} from 're
|
||||
import type {ChangeEvent, ReactNode} from 'react';
|
||||
import {FormattedMessage} from 'react-intl';
|
||||
import ReactSelect from 'react-select';
|
||||
import type {ValueType, OptionsType} from 'react-select';
|
||||
import type {OnChangeValue, Options} from 'react-select';
|
||||
|
||||
import type {UserNotifyProps} from '@mattermost/types/users';
|
||||
|
||||
@@ -88,7 +88,7 @@ function DesktopAndMobileNotificationSettings({
|
||||
setParentState('desktopAndMobileSettingsDifferent', value);
|
||||
}, [setParentState]);
|
||||
|
||||
const handleChangeForSendMobileNotificationsSelect = useCallback((selectedOption: ValueType<SelectOption>) => {
|
||||
const handleChangeForSendMobileNotificationsSelect = useCallback((selectedOption: OnChangeValue<SelectOption, boolean>) => {
|
||||
if (selectedOption && 'value' in selectedOption) {
|
||||
setParentState('pushActivity', selectedOption.value);
|
||||
}
|
||||
@@ -99,7 +99,7 @@ function DesktopAndMobileNotificationSettings({
|
||||
setParentState('pushThreads', value);
|
||||
}, [setParentState]);
|
||||
|
||||
const handleChangeForTriggerMobileNotificationsSelect = useCallback((selectedOption: ValueType<SelectOption>) => {
|
||||
const handleChangeForTriggerMobileNotificationsSelect = useCallback((selectedOption: OnChangeValue<SelectOption, boolean>) => {
|
||||
if (selectedOption && 'value' in selectedOption) {
|
||||
setParentState('pushStatus', selectedOption.value);
|
||||
}
|
||||
@@ -203,7 +203,6 @@ function DesktopAndMobileNotificationSettings({
|
||||
className='react-select singleSelect'
|
||||
classNamePrefix='react-select'
|
||||
options={optionsOfSendNotifications}
|
||||
clearable={false}
|
||||
isClearable={false}
|
||||
isSearchable={false}
|
||||
components={{IndicatorSeparator: NoIndicatorSeparatorComponent}}
|
||||
@@ -257,7 +256,6 @@ function DesktopAndMobileNotificationSettings({
|
||||
className='react-select singleSelect'
|
||||
classNamePrefix='react-select'
|
||||
options={optionsOfSendMobileNotificationsWhenSelect}
|
||||
clearable={false}
|
||||
isClearable={false}
|
||||
isSearchable={false}
|
||||
components={{IndicatorSeparator: NoIndicatorSeparatorComponent}}
|
||||
@@ -426,7 +424,7 @@ function shouldShowSendMobileNotificationsSection(sendPushNotifications: UserSet
|
||||
return false;
|
||||
}
|
||||
|
||||
export function getValueOfSendMobileNotificationForSelect(pushActivity: UserNotifyProps['push']): ValueType<SelectOption> {
|
||||
export function getValueOfSendMobileNotificationForSelect(pushActivity: UserNotifyProps['push']): OnChangeValue<SelectOption, boolean> {
|
||||
if (!pushActivity) {
|
||||
return optionsOfSendNotifications[1];
|
||||
}
|
||||
@@ -462,7 +460,7 @@ export function shouldShowTriggerMobileNotificationsSection(sendPushNotification
|
||||
return true;
|
||||
}
|
||||
|
||||
const optionsOfSendMobileNotificationsWhenSelect: OptionsType<SelectOption> = [
|
||||
const optionsOfSendMobileNotificationsWhenSelect: Options<SelectOption> = [
|
||||
{
|
||||
label: (
|
||||
<FormattedMessage
|
||||
@@ -492,7 +490,7 @@ const optionsOfSendMobileNotificationsWhenSelect: OptionsType<SelectOption> = [
|
||||
},
|
||||
];
|
||||
|
||||
export function getValueOfSendMobileNotificationWhenSelect(pushStatus?: UserNotifyProps['push_status']): ValueType<SelectOption> {
|
||||
export function getValueOfSendMobileNotificationWhenSelect(pushStatus?: UserNotifyProps['push_status']): OnChangeValue<SelectOption, boolean> {
|
||||
if (!pushStatus) {
|
||||
return optionsOfSendMobileNotificationsWhenSelect[2];
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
import type {ChangeEvent, ReactNode} from 'react';
|
||||
import React, {memo, useEffect, useRef, Fragment, useMemo, useCallback} from 'react';
|
||||
import {FormattedMessage, useIntl} from 'react-intl';
|
||||
import type {ValueType} from 'react-select';
|
||||
import type {OnChangeValue} from 'react-select';
|
||||
import ReactSelect from 'react-select';
|
||||
|
||||
import type {UserNotifyProps} from '@mattermost/types/users';
|
||||
@@ -96,7 +96,7 @@ function DesktopNotificationSoundsSettings({
|
||||
}
|
||||
}, [setParentState]);
|
||||
|
||||
const handleChangeForMessageNotificationSoundSelect = useCallback((selectedOption: ValueType<SelectOption>) => {
|
||||
const handleChangeForMessageNotificationSoundSelect = useCallback((selectedOption: OnChangeValue<SelectOption, boolean>) => {
|
||||
stopTryNotificationRing();
|
||||
|
||||
if (selectedOption && 'value' in selectedOption) {
|
||||
@@ -105,7 +105,7 @@ function DesktopNotificationSoundsSettings({
|
||||
}
|
||||
}, [setParentState]);
|
||||
|
||||
const handleChangeForIncomingCallSoundSelect = useCallback((selectedOption: ValueType<SelectOption>) => {
|
||||
const handleChangeForIncomingCallSoundSelect = useCallback((selectedOption: OnChangeValue<SelectOption, boolean>) => {
|
||||
stopTryNotificationRing();
|
||||
|
||||
if (selectedOption && 'value' in selectedOption) {
|
||||
@@ -138,7 +138,6 @@ function DesktopNotificationSoundsSettings({
|
||||
className='react-select inlineSelect'
|
||||
classNamePrefix='react-select'
|
||||
options={optionsOfMessageNotificationSoundsSelect}
|
||||
clearable={false}
|
||||
isClearable={false}
|
||||
isSearchable={false}
|
||||
isDisabled={!isMessageNotificationSoundChecked}
|
||||
@@ -178,7 +177,6 @@ function DesktopNotificationSoundsSettings({
|
||||
className='react-select inlineSelect'
|
||||
classNamePrefix='react-select'
|
||||
options={optionsOfIncomingCallSoundsSelect}
|
||||
clearable={false}
|
||||
isClearable={false}
|
||||
isSearchable={false}
|
||||
isDisabled={!isIncomingCallSoundChecked}
|
||||
|
||||
@@ -7,7 +7,7 @@ import React from 'react';
|
||||
import type {ChangeEvent} from 'react';
|
||||
import type {WrappedComponentProps} from 'react-intl';
|
||||
import {FormattedMessage, injectIntl} from 'react-intl';
|
||||
import type {Styles as ReactSelectStyles, ValueType} from 'react-select';
|
||||
import type {OnChangeValue, StylesConfig} from 'react-select';
|
||||
import CreatableReactSelect from 'react-select/creatable';
|
||||
|
||||
import {LightbulbOutlineIcon} from '@mattermost/compass-icons/components';
|
||||
@@ -369,7 +369,7 @@ class NotificationsTab extends React.PureComponent<Props, State> {
|
||||
this.setState({isCustomKeysWithNotificationInputChecked: checked});
|
||||
};
|
||||
|
||||
handleChangeForCustomKeysWithNotificationInput = (values: ValueType<{ value: string }>) => {
|
||||
handleChangeForCustomKeysWithNotificationInput = (values: OnChangeValue<{ value: string }, true>) => {
|
||||
if (values && Array.isArray(values) && values.length > 0) {
|
||||
// Check the custom keys input checkbox when atleast a single key is entered
|
||||
if (this.state.isCustomKeysWithNotificationInputChecked === false) {
|
||||
@@ -437,7 +437,7 @@ class NotificationsTab extends React.PureComponent<Props, State> {
|
||||
}
|
||||
};
|
||||
|
||||
handleChangeForCustomKeysWithHighlightInput = (values: ValueType<{ value: string }>) => {
|
||||
handleChangeForCustomKeysWithHighlightInput = (values: OnChangeValue<{ value: string }, true>) => {
|
||||
if (values && Array.isArray(values) && values.length > 0) {
|
||||
const customKeysWithHighlight = values.
|
||||
map((value: MultiInputValue) => {
|
||||
@@ -1121,7 +1121,7 @@ class NotificationsTab extends React.PureComponent<Props, State> {
|
||||
}
|
||||
}
|
||||
|
||||
const customKeywordsSelectorStyles: ReactSelectStyles = {
|
||||
const customKeywordsSelectorStyles = {
|
||||
container: ((baseStyle) => ({
|
||||
...baseStyle,
|
||||
marginBlockStart: '10px',
|
||||
@@ -1159,7 +1159,7 @@ const customKeywordsSelectorStyles: ReactSelectStyles = {
|
||||
color: 'rgba(var(--center-channel-color-rgb), 0.56);',
|
||||
},
|
||||
})),
|
||||
};
|
||||
} satisfies StylesConfig<MultiInputValue, true>;
|
||||
|
||||
const validNotificationLevels = Object.values(NotificationLevels);
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ import React from 'react';
|
||||
import type {RefObject} from 'react';
|
||||
import {FormattedMessage} from 'react-intl';
|
||||
import ReactSelect from 'react-select';
|
||||
import type {ValueType} from 'react-select';
|
||||
import type {OnChangeValue, StylesConfig} from 'react-select';
|
||||
|
||||
import type {PreferencesType, PreferenceType} from '@mattermost/types/preferences';
|
||||
|
||||
@@ -94,7 +94,7 @@ export default class LimitVisibleGMsDMs extends React.PureComponent<Props, State
|
||||
}
|
||||
}
|
||||
|
||||
handleChange = (selected: ValueType<Limit>) => {
|
||||
handleChange = (selected: OnChangeValue<Limit, boolean>) => {
|
||||
if (selected && 'value' in selected) {
|
||||
this.setState({limit: selected});
|
||||
}
|
||||
@@ -158,7 +158,7 @@ export default class LimitVisibleGMsDMs extends React.PureComponent<Props, State
|
||||
classNamePrefix='react-select'
|
||||
id='limitVisibleGMsDMs'
|
||||
options={limits}
|
||||
clearable={false}
|
||||
isClearable={false}
|
||||
onChange={this.handleChange}
|
||||
value={this.state.limit}
|
||||
isSearchable={false}
|
||||
@@ -182,8 +182,8 @@ export default class LimitVisibleGMsDMs extends React.PureComponent<Props, State
|
||||
}
|
||||
|
||||
const reactStyles = {
|
||||
menuPortal: (provided: React.CSSProperties) => ({
|
||||
menuPortal: (provided) => ({
|
||||
...provided,
|
||||
zIndex: 9999,
|
||||
}),
|
||||
};
|
||||
} satisfies StylesConfig<Limit, boolean>;
|
||||
|
||||
@@ -47,7 +47,7 @@ exports[`components/widgets/inputs/DropdownInputHybrid should match snapshot 1`]
|
||||
}
|
||||
}
|
||||
>
|
||||
<StateManager
|
||||
<ForwardRef
|
||||
className="Input Input__focus"
|
||||
components={
|
||||
Object {
|
||||
@@ -56,9 +56,6 @@ exports[`components/widgets/inputs/DropdownInputHybrid should match snapshot 1`]
|
||||
"Option": [Function],
|
||||
}
|
||||
}
|
||||
defaultInputValue=""
|
||||
defaultMenuIsOpen={false}
|
||||
defaultValue={null}
|
||||
hideSelectedOptions={true}
|
||||
id="DropdownInput_channel_message_retention"
|
||||
isSearchable={false}
|
||||
|
||||
@@ -33,9 +33,8 @@ describe('components/widgets/inputs/ChannelsInput', () => {
|
||||
/>,
|
||||
);
|
||||
expect(wrapper).toMatchInlineSnapshot(`
|
||||
<Async
|
||||
<ForwardRef
|
||||
aria-label="test"
|
||||
cacheOptions={false}
|
||||
className="ChannelsInput empty"
|
||||
classNamePrefix="channels-input"
|
||||
components={
|
||||
@@ -47,7 +46,6 @@ describe('components/widgets/inputs/ChannelsInput', () => {
|
||||
}
|
||||
defaultMenuIsOpen={false}
|
||||
defaultOptions={false}
|
||||
filterOption={null}
|
||||
formatOptionLabel={[Function]}
|
||||
getOptionValue={[Function]}
|
||||
inputValue=""
|
||||
|
||||
@@ -7,9 +7,9 @@ import type {ComponentProps, RefObject} from 'react';
|
||||
import type {MessageDescriptor} from 'react-intl';
|
||||
import {FormattedMessage, defineMessages} from 'react-intl';
|
||||
import {components} from 'react-select';
|
||||
import type {ValueType, ActionMeta, InputActionMeta} from 'react-select';
|
||||
import type {Async} from 'react-select/async';
|
||||
import type {InputActionMeta, SelectInstance, MultiValue, GroupBase, MultiValueRemoveProps} from 'react-select';
|
||||
import AsyncSelect from 'react-select/async';
|
||||
import type {SelectComponents} from 'react-select/dist/declarations/src/components';
|
||||
|
||||
import type {Channel} from '@mattermost/types/channels';
|
||||
|
||||
@@ -57,7 +57,7 @@ export default class ChannelsInput<T extends Channel> extends React.PureComponen
|
||||
loadingMessage: messages.loading,
|
||||
noOptionsMessage: messages.noOptions,
|
||||
};
|
||||
private selectRef: RefObject<Async<T> & {handleInputChange: (newValue: string, actionMeta: InputActionMeta | {action: 'custom'}) => string}>;
|
||||
private selectRef: RefObject<SelectInstance<T, true>>;
|
||||
|
||||
constructor(props: Props<T>) {
|
||||
super(props);
|
||||
@@ -73,7 +73,7 @@ export default class ChannelsInput<T extends Channel> extends React.PureComponen
|
||||
if (action.action === 'input-blur' && inputValue !== '') {
|
||||
for (const option of this.state.options) {
|
||||
if (this.props.inputValue === option.name) {
|
||||
this.onChange([...this.props.value, option], {} as ActionMeta<T>);
|
||||
this.onChange([...this.props.value, option]);
|
||||
this.props.onInputChange('');
|
||||
return;
|
||||
}
|
||||
@@ -84,12 +84,12 @@ export default class ChannelsInput<T extends Channel> extends React.PureComponen
|
||||
}
|
||||
};
|
||||
|
||||
optionsLoader = (_input: string, callback: (options: T[]) => void) => {
|
||||
optionsLoader = (inputValue: string, callback: (options: T[]) => void) => {
|
||||
const customCallback = (options: T[]) => {
|
||||
this.setState({options});
|
||||
callback(options);
|
||||
};
|
||||
const result = this.props.channelsLoader(this.props.inputValue, customCallback);
|
||||
const result = this.props.channelsLoader(inputValue, customCallback);
|
||||
if (result && result.then) {
|
||||
result.then(customCallback);
|
||||
}
|
||||
@@ -102,8 +102,7 @@ export default class ChannelsInput<T extends Channel> extends React.PureComponen
|
||||
/>
|
||||
);
|
||||
|
||||
// faking types due to longstanding mismatches in react-select & @types/react-select
|
||||
return (<LoadingSpinner text={text}/> as unknown as string);
|
||||
return (<LoadingSpinner text={text}/>);
|
||||
};
|
||||
|
||||
NoOptionsMessage = (props: Record<string, any>) => {
|
||||
@@ -138,34 +137,36 @@ export default class ChannelsInput<T extends Channel> extends React.PureComponen
|
||||
);
|
||||
};
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
onChange = (value: T[], _meta: ActionMeta<T>) => {
|
||||
onChange = (value: MultiValue<T>) => {
|
||||
if (this.props.onChange) {
|
||||
this.props.onChange(value);
|
||||
// Copy value to avoid callers from having to deal with it being readonly
|
||||
this.props.onChange([...value]);
|
||||
}
|
||||
};
|
||||
|
||||
MultiValueRemove = ({children, innerProps}: {children: React.ReactNode | React.ReactNode[]; innerProps: Record<string, any>}) => (
|
||||
<div {...innerProps}>
|
||||
{children || <CloseCircleSolidIcon/>}
|
||||
</div>
|
||||
);
|
||||
MultiValueRemove = (props: MultiValueRemoveProps<T, boolean, GroupBase<T>>) => {
|
||||
const {innerProps, children} = props;
|
||||
|
||||
components = {
|
||||
return (<div {...innerProps}>
|
||||
{children || <CloseCircleSolidIcon/>}
|
||||
</div>);
|
||||
};
|
||||
|
||||
components: Partial<SelectComponents<T, true, GroupBase<T>>> = {
|
||||
NoOptionsMessage: this.NoOptionsMessage,
|
||||
MultiValueRemove: this.MultiValueRemove,
|
||||
IndicatorsContainer: () => null,
|
||||
};
|
||||
|
||||
onFocus = () => {
|
||||
this.selectRef.current?.handleInputChange(this.props.inputValue, {action: 'custom'});
|
||||
this.selectRef.current?.onInputChange(this.props.inputValue, {prevInputValue: this.props.inputValue, action: 'set-value'});
|
||||
};
|
||||
|
||||
render() {
|
||||
return (
|
||||
<AsyncSelect
|
||||
ref={this.selectRef}
|
||||
onChange={this.onChange as (value: ValueType<Channel>, _meta: ActionMeta<Channel>) => void}
|
||||
onChange={this.onChange}
|
||||
|
||||
loadOptions={this.optionsLoader}
|
||||
isMulti={true}
|
||||
|
||||
@@ -3,11 +3,10 @@
|
||||
|
||||
import classNames from 'classnames';
|
||||
import React, {useState, useEffect, useRef} from 'react';
|
||||
import type {CSSProperties} from 'react';
|
||||
import type {MessageDescriptor} from 'react-intl';
|
||||
import {useIntl} from 'react-intl';
|
||||
import ReactSelect, {components} from 'react-select';
|
||||
import type {Props as SelectProps, IndicatorContainerProps, ControlProps, OptionProps} from 'react-select';
|
||||
import type {Props as SelectProps, IndicatorsContainerProps, ControlProps, OptionProps, StylesConfig, SingleValue} from 'react-select';
|
||||
|
||||
import 'components/widgets/inputs/input/input.scss';
|
||||
import './dropdown_input_hybrid.scss';
|
||||
@@ -18,7 +17,7 @@ type OptionType = {
|
||||
value: string;
|
||||
}
|
||||
|
||||
type Props<T extends OptionType> = Omit<SelectProps<T>, 'onChange'> & {
|
||||
type Props<T extends OptionType> = Omit<SelectProps<T>, 'onChange' | 'onInputChange' | 'isMulti'> & {
|
||||
value: T;
|
||||
legend?: string | MessageDescriptor;
|
||||
error?: string;
|
||||
@@ -37,11 +36,11 @@ type Props<T extends OptionType> = Omit<SelectProps<T>, 'onChange'> & {
|
||||
};
|
||||
|
||||
const baseStyles = {
|
||||
input: (provided: CSSProperties) => ({
|
||||
input: (provided) => ({
|
||||
...provided,
|
||||
color: 'var(--center-channel-color)',
|
||||
}),
|
||||
control: (provided: CSSProperties) => ({
|
||||
control: (provided) => ({
|
||||
...provided,
|
||||
border: 'none',
|
||||
boxShadow: 'none',
|
||||
@@ -50,17 +49,17 @@ const baseStyles = {
|
||||
minHeight: '40px',
|
||||
borderRadius: '0',
|
||||
}),
|
||||
indicatorSeparator: (provided: CSSProperties) => ({
|
||||
indicatorSeparator: (provided) => ({
|
||||
...provided,
|
||||
display: 'none',
|
||||
}),
|
||||
menuPortal: (provided: CSSProperties) => ({
|
||||
menuPortal: (provided) => ({
|
||||
...provided,
|
||||
zIndex: 99999999,
|
||||
}),
|
||||
};
|
||||
} satisfies StylesConfig<OptionType, boolean>;
|
||||
|
||||
const IndicatorsContainer = (props: IndicatorContainerProps<OptionType>) => (
|
||||
const IndicatorsContainer = <T extends OptionType>(props: IndicatorsContainerProps<T>) => (
|
||||
<div className='DropdownInput__indicatorsContainer'>
|
||||
<components.IndicatorsContainer {...props}>
|
||||
<i className='icon icon-chevron-down'/>
|
||||
@@ -68,13 +67,13 @@ const IndicatorsContainer = (props: IndicatorContainerProps<OptionType>) => (
|
||||
</div>
|
||||
);
|
||||
|
||||
const Control = (props: ControlProps<OptionType>) => (
|
||||
const Control = <T extends OptionType>(props: ControlProps<T>) => (
|
||||
<div className='DropdownInput__controlContainer'>
|
||||
<components.Control {...props}/>
|
||||
</div>
|
||||
);
|
||||
|
||||
const Option = (props: OptionProps<OptionType>) => (
|
||||
const Option = <T extends OptionType>(props: OptionProps<T>) => (
|
||||
<div
|
||||
className={classNames('DropdownInput__option', {
|
||||
selected: props.isSelected,
|
||||
@@ -134,30 +133,35 @@ const DropdownInputHybrid = <T extends OptionType = OptionType>(props: Props<T>)
|
||||
|
||||
const getMenuStyles = () =>
|
||||
(showInput ? {
|
||||
menu: (provided: CSSProperties) => ({
|
||||
menu: (provided) => ({
|
||||
...provided,
|
||||
width: containerRef.current ? `${containerRef.current.offsetWidth}px` : '0px',
|
||||
left: inputRef.current ? `-${inputRef.current.offsetWidth}px` : '0px',
|
||||
}),
|
||||
} : {});
|
||||
} satisfies StylesConfig<OptionType, boolean> : {});
|
||||
|
||||
const onInputBlur = () => setInputFocused(false);
|
||||
|
||||
const onInputFocus = () => setInputFocused(true);
|
||||
|
||||
const onDropdownInputFocus = (event: React.FocusEvent<HTMLElement>) => {
|
||||
const onDropdownInputFocus = (event: React.FocusEvent<HTMLInputElement>) => {
|
||||
setFocused(true);
|
||||
|
||||
props.onFocus?.(event);
|
||||
};
|
||||
|
||||
const onDropdownInputBlur = (event: React.FocusEvent<HTMLElement>) => {
|
||||
const onDropdownInputBlur = (event: React.FocusEvent<HTMLInputElement>) => {
|
||||
setFocused(false);
|
||||
|
||||
props.onBlur?.(event);
|
||||
};
|
||||
|
||||
const onValueChange = (event: T) => {
|
||||
const onValueChange = (event: SingleValue<T>) => {
|
||||
if (!event) {
|
||||
// This case doesn't seem possible with the way that we're using ReactSelect
|
||||
return;
|
||||
}
|
||||
|
||||
showTextInput(event.value);
|
||||
|
||||
onDropdownChange(event);
|
||||
@@ -213,7 +217,7 @@ const DropdownInputHybrid = <T extends OptionType = OptionType>(props: Props<T>)
|
||||
className={classNames('Input form-control')}
|
||||
ref={inputRef}
|
||||
id={inputId}
|
||||
disabled={props.disabled}
|
||||
disabled={props.isDisabled}
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
@@ -224,7 +228,7 @@ const DropdownInputHybrid = <T extends OptionType = OptionType>(props: Props<T>)
|
||||
width: showInput ? `${width}px` : '100%',
|
||||
}}
|
||||
>
|
||||
<ReactSelect
|
||||
<ReactSelect<T>
|
||||
id={`DropdownInput_${name}`}
|
||||
placeholder={focused ? '' : placeholder}
|
||||
components={{
|
||||
@@ -234,13 +238,13 @@ const DropdownInputHybrid = <T extends OptionType = OptionType>(props: Props<T>)
|
||||
}}
|
||||
className={classNames('Input', className, {Input__focus: showLegend})}
|
||||
classNamePrefix={dropdownClassNamePrefix}
|
||||
onChange={onValueChange as any}
|
||||
onChange={onValueChange}
|
||||
styles={{...baseStyles, ...getMenuStyles()}}
|
||||
value={value}
|
||||
hideSelectedOptions={true}
|
||||
isSearchable={false}
|
||||
menuPortalTarget={document.body}
|
||||
isDisabled={props.disabled}
|
||||
isDisabled={props.isDisabled}
|
||||
{...otherProps}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -62,6 +62,10 @@
|
||||
.users-emails-input__input {
|
||||
border-bottom: 0;
|
||||
|
||||
&-container{
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.a11y--focused {
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
@@ -36,9 +36,8 @@ describe('components/widgets/inputs/UsersEmailsInput', () => {
|
||||
);
|
||||
expect(wrapper).toMatchInlineSnapshot(`
|
||||
<Fragment>
|
||||
<Async
|
||||
<ForwardRef
|
||||
aria-label="test"
|
||||
cacheOptions={false}
|
||||
className="UsersEmailsInput empty"
|
||||
classNamePrefix="users-emails-input"
|
||||
components={
|
||||
@@ -51,7 +50,6 @@ describe('components/widgets/inputs/UsersEmailsInput', () => {
|
||||
}
|
||||
defaultMenuIsOpen={false}
|
||||
defaultOptions={false}
|
||||
filterOption={null}
|
||||
formatOptionLabel={[Function]}
|
||||
getOptionValue={[Function]}
|
||||
inputValue=""
|
||||
|
||||
@@ -7,7 +7,7 @@ import type {RefObject} from 'react';
|
||||
import type {MessageDescriptor} from 'react-intl';
|
||||
import {FormattedMessage, defineMessages} from 'react-intl';
|
||||
import {components} from 'react-select';
|
||||
import type {FormatOptionLabelMeta, InputActionMeta, InputProps, OptionsType, Styles, ValueType} from 'react-select';
|
||||
import type {FormatOptionLabelMeta, InputActionMeta, InputProps, Options, StylesConfig, SelectInstance, MultiValue, SingleValue, OptionsOrGroups, GroupBase, MultiValueRemoveProps} from 'react-select';
|
||||
import AsyncCreatable from 'react-select/async-creatable';
|
||||
|
||||
import type {UserProfile} from '@mattermost/types/users';
|
||||
@@ -59,6 +59,7 @@ export type EmailInvite = {
|
||||
|
||||
type State = {
|
||||
options: UserProfile[];
|
||||
prevValue: string;
|
||||
}
|
||||
|
||||
const multipleValuesDelimiter = /[\s,;]+/;
|
||||
@@ -85,13 +86,14 @@ export default class UsersEmailsInput extends React.PureComponent<Props, State>
|
||||
loadingMessage: messages.loadingDefault,
|
||||
showError: false,
|
||||
};
|
||||
private selectRef: RefObject<AsyncCreatable<UserProfile | EmailInvite> & { handleInputChange: (newValue: string, actionMeta: InputActionMeta | { action: 'custom' }) => string }>;
|
||||
private selectRef: RefObject<SelectInstance<UserProfile | EmailInvite, true>>;
|
||||
|
||||
constructor(props: Props) {
|
||||
super(props);
|
||||
this.selectRef = React.createRef();
|
||||
this.state = {
|
||||
options: [],
|
||||
prevValue: this.props.inputValue,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -187,7 +189,7 @@ export default class UsersEmailsInput extends React.PureComponent<Props, State>
|
||||
);
|
||||
};
|
||||
|
||||
onChange = (value: ValueType<UserProfile | EmailInvite>) => {
|
||||
onChange = (value: MultiValue<EmailInvite | UserProfile> | SingleValue<EmailInvite | UserProfile>) => {
|
||||
if (this.props.onChange) {
|
||||
if (value) {
|
||||
this.props.onChange((value as Array<UserProfile | EmailInvite>).map((v) => {
|
||||
@@ -214,7 +216,7 @@ export default class UsersEmailsInput extends React.PureComponent<Props, State>
|
||||
</>
|
||||
);
|
||||
|
||||
Input = (props: InputProps) => {
|
||||
Input = (props: InputProps<EmailInvite | UserProfile, true>) => {
|
||||
const handlePaste = (e: ClipboardEvent) => {
|
||||
e.preventDefault();
|
||||
const clipboardText = e.clipboardData?.getData('Text') || '';
|
||||
@@ -257,11 +259,13 @@ export default class UsersEmailsInput extends React.PureComponent<Props, State>
|
||||
);
|
||||
};
|
||||
|
||||
MultiValueRemove = ({children, innerProps}: {children: React.ReactNode | React.ReactNodeArray; innerProps: Record<string, any>}) => (
|
||||
<div {...innerProps}>
|
||||
MultiValueRemove = (props: MultiValueRemoveProps<EmailInvite | UserProfile, true>) => {
|
||||
const {children, innerProps} = props;
|
||||
|
||||
return (<div {...innerProps}>
|
||||
{children || <CloseCircleSolidIcon/>}
|
||||
</div>
|
||||
);
|
||||
</div>);
|
||||
};
|
||||
|
||||
components = {
|
||||
NoOptionsMessage: this.props.suppressNoOptionsMessage ? () => null : this.NoOptionsMessage,
|
||||
@@ -271,35 +275,47 @@ export default class UsersEmailsInput extends React.PureComponent<Props, State>
|
||||
};
|
||||
|
||||
handleInputChange = async (inputValue: string, action: InputActionMeta) => {
|
||||
if (action.action === 'input-blur' && inputValue !== '') {
|
||||
if (action.action === 'input-blur' && action.prevInputValue !== '') {
|
||||
const values = this.formatValuesForCreatable();
|
||||
|
||||
// Check if the input is an existing user by username or email.
|
||||
const option = this.state.options.find((o) =>
|
||||
this.props.inputValue === o.username || this.props.inputValue === ('@' + o.username) ||
|
||||
this.props.inputValue === o.email,
|
||||
action.prevInputValue === o.username || action.prevInputValue === ('@' + o.username) ||
|
||||
action.prevInputValue === o.email,
|
||||
);
|
||||
|
||||
if (option) {
|
||||
this.onChange([...values, option]);
|
||||
this.props.onInputChange('');
|
||||
this.setState((state) => ({
|
||||
...state,
|
||||
prevValue: action.prevInputValue,
|
||||
}));
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if the input is a valid new email, if the email invitations are enabled.
|
||||
if (this.props.emailInvitationsEnabled && isEmail(this.props.inputValue)) {
|
||||
const email = this.props.inputValue;
|
||||
if (this.props.emailInvitationsEnabled && isEmail(action.prevInputValue)) {
|
||||
const email = action.prevInputValue;
|
||||
this.onChange([...values, {value: email, label: email}]);
|
||||
this.props.onInputChange('');
|
||||
this.setState((state) => ({
|
||||
...state,
|
||||
prevValue: action.prevInputValue,
|
||||
}));
|
||||
}
|
||||
} else if (action.action === 'input-change' && inputValue !== '' && inputValue?.[inputValue.length - 1].match(multipleValuesDelimiter)) {
|
||||
const newValuesCount = await this.appendDelimitedValues(inputValue);
|
||||
} else if (action.action === 'input-change' && action.prevInputValue !== '' && action.prevInputValue?.[action.prevInputValue.length - 1].match(multipleValuesDelimiter)) {
|
||||
const newValuesCount = await this.appendDelimitedValues(action.prevInputValue);
|
||||
if (newValuesCount === 0) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (action.action !== 'input-blur' && action.action !== 'menu-close') {
|
||||
this.props.onInputChange(inputValue);
|
||||
this.setState((state) => ({
|
||||
...state,
|
||||
prevValue: action.prevInputValue,
|
||||
}));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -327,16 +343,16 @@ export default class UsersEmailsInput extends React.PureComponent<Props, State>
|
||||
}
|
||||
};
|
||||
|
||||
showAddEmail = (inputValue: string, value: ValueType<UserProfile | EmailInvite>, options: OptionsType<UserProfile | EmailInvite>): boolean => {
|
||||
showAddEmail = (inputValue: string, value: Options<UserProfile | EmailInvite>, options: OptionsOrGroups<EmailInvite | UserProfile, GroupBase<EmailInvite | UserProfile>>): boolean => {
|
||||
return this.props.emailInvitationsEnabled && options.length === 0 && isEmail(inputValue);
|
||||
};
|
||||
|
||||
onFocus = () => {
|
||||
this.selectRef.current?.handleInputChange(this.props.inputValue, {action: 'custom'});
|
||||
this.selectRef.current?.onInputChange(this.props.inputValue, {action: 'set-value', prevInputValue: this.props.inputValue});
|
||||
};
|
||||
|
||||
onBlur = () => {
|
||||
this.selectRef.current?.handleInputChange(this.props.inputValue, {action: 'input-blur'});
|
||||
this.selectRef.current?.onInputChange(this.props.inputValue, {action: 'input-blur', prevInputValue: this.state.prevValue});
|
||||
if (this.props.onBlur) {
|
||||
this.props.onBlur();
|
||||
}
|
||||
@@ -460,7 +476,7 @@ export default class UsersEmailsInput extends React.PureComponent<Props, State>
|
||||
|
||||
const Msg: any = components.NoOptionsMessage;
|
||||
|
||||
const styles: Partial<Styles> = {
|
||||
const styles = {
|
||||
placeholder: (css) => ({
|
||||
...css,
|
||||
|
||||
@@ -482,7 +498,7 @@ export default class UsersEmailsInput extends React.PureComponent<Props, State>
|
||||
textAlign: 'left',
|
||||
},
|
||||
}),
|
||||
};
|
||||
} satisfies StylesConfig<UserProfile | EmailInvite, true >;
|
||||
|
||||
return (
|
||||
<>
|
||||
@@ -511,8 +527,8 @@ export default class UsersEmailsInput extends React.PureComponent<Props, State>
|
||||
onInputChange={this.handleInputChange}
|
||||
inputValue={this.props.inputValue}
|
||||
openMenuOnFocus={true}
|
||||
onFocus={this.onFocus}
|
||||
onBlur={this.onBlur}
|
||||
onFocus={() => this.onFocus}
|
||||
onBlur={() => this.onBlur}
|
||||
tabSelectsValue={true}
|
||||
value={values}
|
||||
aria-label={this.props.ariaLabel}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
import type {ReactNode} from 'react';
|
||||
import React from 'react';
|
||||
import ReactSelect from 'react-select';
|
||||
import type {ValueType} from 'react-select';
|
||||
import type {OnChangeValue} from 'react-select';
|
||||
|
||||
import type {BaseSettingItemProps} from './base_setting_item';
|
||||
import BaseSettingItem from './base_setting_item';
|
||||
@@ -20,7 +20,7 @@ type Props = BaseSettingItemProps & {
|
||||
handleCheckboxChange: (e: boolean) => void;
|
||||
selectFieldData: FieldsetReactSelect;
|
||||
selectFieldValue?: Option;
|
||||
handleSelectChange: (selected: ValueType<Option>) => void;
|
||||
handleSelectChange: (selected: OnChangeValue<Option, boolean>) => void;
|
||||
isSelectDisabled?: boolean;
|
||||
selectPlaceholder?: string;
|
||||
}
|
||||
@@ -66,7 +66,6 @@ export default function CheckboxWithSelectSettingItem({
|
||||
className='react-select singleSelect react-select-top'
|
||||
classNamePrefix='react-select'
|
||||
options={selectFieldData.options}
|
||||
clearable={selectFieldData.clearable}
|
||||
isClearable={selectFieldData.clearable}
|
||||
isDisabled={isSelectDisabled}
|
||||
isSearchable={false}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
import type {ReactNode} from 'react';
|
||||
import React from 'react';
|
||||
import type {ValueType} from 'react-select';
|
||||
import type {OnChangeValue} from 'react-select';
|
||||
import ReactSelect from 'react-select';
|
||||
|
||||
import type {BaseSettingItemProps} from './base_setting_item';
|
||||
@@ -27,7 +27,7 @@ export type FieldsetReactSelect = {
|
||||
type Props = BaseSettingItemProps & {
|
||||
inputFieldData: FieldsetReactSelect;
|
||||
inputFieldValue: Option;
|
||||
handleChange: (selected: ValueType<Option>) => void;
|
||||
handleChange: (selected: OnChangeValue<Option, boolean>) => void;
|
||||
}
|
||||
|
||||
function ReactSelectItemCreator({
|
||||
@@ -47,7 +47,6 @@ function ReactSelectItemCreator({
|
||||
className='react-select singleSelect react-select-top'
|
||||
classNamePrefix='react-select'
|
||||
options={inputFieldData.options}
|
||||
clearable={inputFieldData.clearable}
|
||||
isClearable={inputFieldData.clearable}
|
||||
isSearchable={false}
|
||||
onChange={handleChange}
|
||||
|
||||
@@ -123,6 +123,10 @@
|
||||
&__input,
|
||||
.react-select__input {
|
||||
color: var(--sys-center-channel-color);
|
||||
|
||||
&-container{
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.app__body & {
|
||||
color: var(--center-channel-color);
|
||||
|
||||
372
webapp/package-lock.json
сгенерированный
372
webapp/package-lock.json
сгенерированный
@@ -128,7 +128,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",
|
||||
@@ -183,7 +183,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",
|
||||
@@ -485,44 +484,38 @@
|
||||
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
|
||||
},
|
||||
"channels/node_modules/react-select": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/react-select/-/react-select-3.0.3.tgz",
|
||||
"integrity": "sha512-/WmzNDvATL2mFMLtZYlfUBHzg6YywglkmwJ52TCuvj2ALNu8gRKSlhkivPfKUWxxWKbolVCXSAh+xuwOQZJykg==",
|
||||
"version": "5.9.0",
|
||||
"resolved": "https://registry.npmjs.org/react-select/-/react-select-5.9.0.tgz",
|
||||
"integrity": "sha512-nwRKGanVHGjdccsnzhFte/PULziueZxGD8LL2WojON78Mvnq7LdAMEtu2frrwld1fr3geixg3iiMBIc/LLAZpw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.4.4",
|
||||
"@emotion/cache": "^10.0.9",
|
||||
"@emotion/core": "^10.0.9",
|
||||
"@emotion/css": "^10.0.9",
|
||||
"classnames": "^2.2.5",
|
||||
"memoize-one": "^5.0.0",
|
||||
"@babel/runtime": "^7.12.0",
|
||||
"@emotion/cache": "^11.4.0",
|
||||
"@emotion/react": "^11.8.1",
|
||||
"@floating-ui/dom": "^1.0.1",
|
||||
"@types/react-transition-group": "^4.4.0",
|
||||
"memoize-one": "^6.0.0",
|
||||
"prop-types": "^15.6.0",
|
||||
"raf": "^3.4.0",
|
||||
"react-input-autosize": "^2.2.1",
|
||||
"react-transition-group": "^2.2.1"
|
||||
"react-transition-group": "^4.3.0",
|
||||
"use-isomorphic-layout-effect": "^1.2.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^16.8.0",
|
||||
"react-dom": "^16.8.0"
|
||||
"react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0",
|
||||
"react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
|
||||
}
|
||||
},
|
||||
"channels/node_modules/react-select/node_modules/memoize-one": {
|
||||
"version": "5.2.1",
|
||||
"resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-5.2.1.tgz",
|
||||
"integrity": "sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q=="
|
||||
},
|
||||
"channels/node_modules/react-select/node_modules/react-transition-group": {
|
||||
"version": "2.9.0",
|
||||
"resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-2.9.0.tgz",
|
||||
"integrity": "sha512-+HzNTCHpeQyl4MJ/bdE0u6XRMe9+XG/+aL4mCxVN4DnPBQ0/5bfHWPDuOZUzYdMj94daZaZdCCc1Dzt9R/xSSg==",
|
||||
"dependencies": {
|
||||
"dom-helpers": "^3.4.0",
|
||||
"loose-envify": "^1.4.0",
|
||||
"prop-types": "^15.6.2",
|
||||
"react-lifecycles-compat": "^3.0.4"
|
||||
},
|
||||
"channels/node_modules/react-select/node_modules/use-isomorphic-layout-effect": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/use-isomorphic-layout-effect/-/use-isomorphic-layout-effect-1.2.0.tgz",
|
||||
"integrity": "sha512-q6ayo8DWoPZT0VdG4u3D3uxcgONP3Mevx2i2b0434cwWBoL+aelL1DzkXI6w3PhTZzUeR2kaVlZn70iCiseP6w==",
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"react": ">=15.0.0",
|
||||
"react-dom": ">=15.0.0"
|
||||
"react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"channels/node_modules/strip-ansi": {
|
||||
@@ -2605,47 +2598,114 @@
|
||||
"url": "https://github.com/sponsors/wooorm"
|
||||
}
|
||||
},
|
||||
"node_modules/@emotion/cache": {
|
||||
"version": "10.0.29",
|
||||
"resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-10.0.29.tgz",
|
||||
"integrity": "sha512-fU2VtSVlHiF27empSbxi1O2JFdNWZO+2NFHfwO0pxgTep6Xa3uGb+3pVKfLww2l/IBGLNEZl5Xf/++A4wAYDYQ==",
|
||||
"node_modules/@emotion/babel-plugin": {
|
||||
"version": "11.13.5",
|
||||
"resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.13.5.tgz",
|
||||
"integrity": "sha512-pxHCpT2ex+0q+HH91/zsdHkw/lXd468DIN2zvfvLtPKLLMo6gQj7oLObq8PhkrxOZb/gGCq03S3Z7PDhS8pduQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@emotion/sheet": "0.9.4",
|
||||
"@emotion/stylis": "0.8.5",
|
||||
"@emotion/utils": "0.11.3",
|
||||
"@emotion/weak-memoize": "0.2.5"
|
||||
"@babel/helper-module-imports": "^7.16.7",
|
||||
"@babel/runtime": "^7.18.3",
|
||||
"@emotion/hash": "^0.9.2",
|
||||
"@emotion/memoize": "^0.9.0",
|
||||
"@emotion/serialize": "^1.3.3",
|
||||
"babel-plugin-macros": "^3.1.0",
|
||||
"convert-source-map": "^1.5.0",
|
||||
"escape-string-regexp": "^4.0.0",
|
||||
"find-root": "^1.1.0",
|
||||
"source-map": "^0.5.7",
|
||||
"stylis": "4.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@emotion/core": {
|
||||
"version": "10.3.1",
|
||||
"resolved": "https://registry.npmjs.org/@emotion/core/-/core-10.3.1.tgz",
|
||||
"integrity": "sha512-447aUEjPIm0MnE6QYIaFz9VQOHSXf4Iu6EWOIqq11EAPqinkSZmfymPTmlOE3QjLv846lH4JVZBUOtwGbuQoww==",
|
||||
"node_modules/@emotion/babel-plugin/node_modules/@emotion/hash": {
|
||||
"version": "0.9.2",
|
||||
"resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.2.tgz",
|
||||
"integrity": "sha512-MyqliTZGuOm3+5ZRSaaBGP3USLw6+EGykkwZns2EPC5g8jJ4z9OrdZY9apkl3+UP9+sdz76YYkwCKP5gh8iY3g==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@emotion/babel-plugin/node_modules/@emotion/serialize": {
|
||||
"version": "1.3.3",
|
||||
"resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.3.3.tgz",
|
||||
"integrity": "sha512-EISGqt7sSNWHGI76hC7x1CksiXPahbxEOrC5RjmFRJTqLyEK9/9hZvBbiYn70dw4wuwMKiEMCUlR6ZXTSWQqxA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.5.5",
|
||||
"@emotion/cache": "^10.0.27",
|
||||
"@emotion/css": "^10.0.27",
|
||||
"@emotion/serialize": "^0.11.15",
|
||||
"@emotion/sheet": "0.9.4",
|
||||
"@emotion/utils": "0.11.3"
|
||||
"@emotion/hash": "^0.9.2",
|
||||
"@emotion/memoize": "^0.9.0",
|
||||
"@emotion/unitless": "^0.10.0",
|
||||
"@emotion/utils": "^1.4.2",
|
||||
"csstype": "^3.0.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@emotion/babel-plugin/node_modules/@emotion/unitless": {
|
||||
"version": "0.10.0",
|
||||
"resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.10.0.tgz",
|
||||
"integrity": "sha512-dFoMUuQA20zvtVTuxZww6OHoJYgrzfKM1t52mVySDJnMSEa08ruEvdYQbhvyu6soU+NeLVd3yKfTfT0NeV6qGg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@emotion/babel-plugin/node_modules/babel-plugin-macros": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz",
|
||||
"integrity": "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.12.5",
|
||||
"cosmiconfig": "^7.0.0",
|
||||
"resolve": "^1.19.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=16.3.0"
|
||||
"engines": {
|
||||
"node": ">=10",
|
||||
"npm": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/@emotion/css": {
|
||||
"version": "10.0.27",
|
||||
"resolved": "https://registry.npmjs.org/@emotion/css/-/css-10.0.27.tgz",
|
||||
"integrity": "sha512-6wZjsvYeBhyZQYNrGoR5yPMYbMBNEnanDrqmsqS1mzDm1cOTu12shvl2j4QHNS36UaTE0USIJawCH9C8oW34Zw==",
|
||||
"node_modules/@emotion/babel-plugin/node_modules/cosmiconfig": {
|
||||
"version": "7.1.0",
|
||||
"resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz",
|
||||
"integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@emotion/serialize": "^0.11.15",
|
||||
"@emotion/utils": "0.11.3",
|
||||
"babel-plugin-emotion": "^10.0.27"
|
||||
"@types/parse-json": "^4.0.0",
|
||||
"import-fresh": "^3.2.1",
|
||||
"parse-json": "^5.0.0",
|
||||
"path-type": "^4.0.0",
|
||||
"yaml": "^1.10.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/@emotion/hash": {
|
||||
"version": "0.8.0",
|
||||
"resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.8.0.tgz",
|
||||
"integrity": "sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow=="
|
||||
"node_modules/@emotion/babel-plugin/node_modules/escape-string-regexp": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
|
||||
"integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/@emotion/babel-plugin/node_modules/source-map": {
|
||||
"version": "0.5.7",
|
||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
|
||||
"integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==",
|
||||
"license": "BSD-3-Clause",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@emotion/cache": {
|
||||
"version": "11.14.0",
|
||||
"resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.14.0.tgz",
|
||||
"integrity": "sha512-L/B1lc/TViYk4DcpGxtAVbx0ZyiKM5ktoIyafGkH6zg/tj+mA+NE//aPYKG0k8kCHSHVJrpLpcAlOBEXQ3SavA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@emotion/memoize": "^0.9.0",
|
||||
"@emotion/sheet": "^1.4.0",
|
||||
"@emotion/utils": "^1.4.2",
|
||||
"@emotion/weak-memoize": "^0.4.0",
|
||||
"stylis": "4.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@emotion/is-prop-valid": {
|
||||
"version": "1.3.1",
|
||||
@@ -2660,32 +2720,60 @@
|
||||
"resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.9.0.tgz",
|
||||
"integrity": "sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ=="
|
||||
},
|
||||
"node_modules/@emotion/serialize": {
|
||||
"version": "0.11.16",
|
||||
"resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-0.11.16.tgz",
|
||||
"integrity": "sha512-G3J4o8by0VRrO+PFeSc3js2myYNOXVJ3Ya+RGVxnshRYgsvErfAOglKAiy1Eo1vhzxqtUvjCyS5gtewzkmvSSg==",
|
||||
"node_modules/@emotion/react": {
|
||||
"version": "11.14.0",
|
||||
"resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.14.0.tgz",
|
||||
"integrity": "sha512-O000MLDBDdk/EohJPFUqvnp4qnHeYkVP5B0xEG0D/L7cOKP9kefu2DXn8dj74cQfsEzUqh+sr1RzFqiL1o+PpA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@emotion/hash": "0.8.0",
|
||||
"@emotion/memoize": "0.7.4",
|
||||
"@emotion/unitless": "0.7.5",
|
||||
"@emotion/utils": "0.11.3",
|
||||
"csstype": "^2.5.7"
|
||||
"@babel/runtime": "^7.18.3",
|
||||
"@emotion/babel-plugin": "^11.13.5",
|
||||
"@emotion/cache": "^11.14.0",
|
||||
"@emotion/serialize": "^1.3.3",
|
||||
"@emotion/use-insertion-effect-with-fallbacks": "^1.2.0",
|
||||
"@emotion/utils": "^1.4.2",
|
||||
"@emotion/weak-memoize": "^0.4.0",
|
||||
"hoist-non-react-statics": "^3.3.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=16.8.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@emotion/serialize/node_modules/@emotion/memoize": {
|
||||
"version": "0.7.4",
|
||||
"resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.7.4.tgz",
|
||||
"integrity": "sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw=="
|
||||
"node_modules/@emotion/react/node_modules/@emotion/hash": {
|
||||
"version": "0.9.2",
|
||||
"resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.2.tgz",
|
||||
"integrity": "sha512-MyqliTZGuOm3+5ZRSaaBGP3USLw6+EGykkwZns2EPC5g8jJ4z9OrdZY9apkl3+UP9+sdz76YYkwCKP5gh8iY3g==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@emotion/serialize/node_modules/csstype": {
|
||||
"version": "2.6.21",
|
||||
"resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.21.tgz",
|
||||
"integrity": "sha512-Z1PhmomIfypOpoMjRQB70jfvy/wxT50qW08YXO5lMIJkrdq4yOTR+AW7FqutScmB9NkLwxo+jU+kZLbofZZq/w=="
|
||||
"node_modules/@emotion/react/node_modules/@emotion/serialize": {
|
||||
"version": "1.3.3",
|
||||
"resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.3.3.tgz",
|
||||
"integrity": "sha512-EISGqt7sSNWHGI76hC7x1CksiXPahbxEOrC5RjmFRJTqLyEK9/9hZvBbiYn70dw4wuwMKiEMCUlR6ZXTSWQqxA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@emotion/hash": "^0.9.2",
|
||||
"@emotion/memoize": "^0.9.0",
|
||||
"@emotion/unitless": "^0.10.0",
|
||||
"@emotion/utils": "^1.4.2",
|
||||
"csstype": "^3.0.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@emotion/react/node_modules/@emotion/unitless": {
|
||||
"version": "0.10.0",
|
||||
"resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.10.0.tgz",
|
||||
"integrity": "sha512-dFoMUuQA20zvtVTuxZww6OHoJYgrzfKM1t52mVySDJnMSEa08ruEvdYQbhvyu6soU+NeLVd3yKfTfT0NeV6qGg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@emotion/sheet": {
|
||||
"version": "0.9.4",
|
||||
"resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-0.9.4.tgz",
|
||||
"integrity": "sha512-zM9PFmgVSqBw4zL101Q0HrBVTGmpAxFZH/pYx/cjJT5advXguvcgjHFTCaIO3enL/xr89vK2bh0Mfyj9aa0ANA=="
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.4.0.tgz",
|
||||
"integrity": "sha512-fTBW9/8r2w3dXWYM4HCB1Rdp8NLibOw2+XELH5m5+AkWiL/KqYX6dc0kKYlaYyKjrQ6ds33MCdMPEwgs2z1rqg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@emotion/stylis": {
|
||||
"version": "0.8.5",
|
||||
@@ -2697,15 +2785,26 @@
|
||||
"resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.7.5.tgz",
|
||||
"integrity": "sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg=="
|
||||
},
|
||||
"node_modules/@emotion/use-insertion-effect-with-fallbacks": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.2.0.tgz",
|
||||
"integrity": "sha512-yJMtVdH59sxi/aVJBpk9FQq+OR8ll5GT8oWd57UpeaKEVGab41JWaCFA7FRLoMLloOZF/c/wsPoe+bfGmRKgDg==",
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"react": ">=16.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@emotion/utils": {
|
||||
"version": "0.11.3",
|
||||
"resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-0.11.3.tgz",
|
||||
"integrity": "sha512-0o4l6pZC+hI88+bzuaX/6BgOvQVhbt2PfmxauVaYOGgbsAw14wdKyvMCZXnsnsHys94iadcF+RG/wZyx6+ZZBw=="
|
||||
"version": "1.4.2",
|
||||
"resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.4.2.tgz",
|
||||
"integrity": "sha512-3vLclRofFziIa3J2wDh9jjbkUz9qk5Vi3IZ/FSTKViB0k+ef0fPV7dYrUIugbgupYDx7v9ud/SjrtEP8Y4xLoA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@emotion/weak-memoize": {
|
||||
"version": "0.2.5",
|
||||
"resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.2.5.tgz",
|
||||
"integrity": "sha512-6U71C2Wp7r5XtFtQzYrW5iKFT67OixrSxjI4MptCHzdSVlgabczzqLe0ZSgnub/5Kp4hSbpDB1tMytZY9pwxxA=="
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.4.0.tgz",
|
||||
"integrity": "sha512-snKqtPW01tN0ui7yu9rGv69aJXr/a/Ywvl11sUjNtEcRc+ng/mQriFL0wLXMef74iHa/EkftbDzU9F8iFbH+zg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@eslint-community/eslint-utils": {
|
||||
"version": "4.4.1",
|
||||
@@ -5572,21 +5671,6 @@
|
||||
"stylis": "4.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@mui/styled-engine/node_modules/@emotion/sheet": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.4.0.tgz",
|
||||
"integrity": "sha512-fTBW9/8r2w3dXWYM4HCB1Rdp8NLibOw2+XELH5m5+AkWiL/KqYX6dc0kKYlaYyKjrQ6ds33MCdMPEwgs2z1rqg=="
|
||||
},
|
||||
"node_modules/@mui/styled-engine/node_modules/@emotion/utils": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.4.1.tgz",
|
||||
"integrity": "sha512-BymCXzCG3r72VKJxaYVwOXATqXIZ85cuvg0YOUDxMGNrKc1DJRZk8MgV5wyXRyEayIMd4FuXJIUgTBXvDNW5cA=="
|
||||
},
|
||||
"node_modules/@mui/styled-engine/node_modules/@emotion/weak-memoize": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.4.0.tgz",
|
||||
"integrity": "sha512-snKqtPW01tN0ui7yu9rGv69aJXr/a/Ywvl11sUjNtEcRc+ng/mQriFL0wLXMef74iHa/EkftbDzU9F8iFbH+zg=="
|
||||
},
|
||||
"node_modules/@mui/system": {
|
||||
"version": "5.16.7",
|
||||
"resolved": "https://registry.npmjs.org/@mui/system/-/system-5.16.7.tgz",
|
||||
@@ -7095,17 +7179,6 @@
|
||||
"@types/react-router": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/react-select": {
|
||||
"version": "3.0.19",
|
||||
"resolved": "https://registry.npmjs.org/@types/react-select/-/react-select-3.0.19.tgz",
|
||||
"integrity": "sha512-d+6qtfFXZeIOAABlVL1e50RZn8ctOABE4tFDxM6KW4lKuXgTTgLVrSik5AX9XjBjV7N80FtS6GTN/WeoXL9Jww==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@types/react": "*",
|
||||
"@types/react-dom": "*",
|
||||
"@types/react-transition-group": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/react-transition-group": {
|
||||
"version": "4.4.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.5.tgz",
|
||||
@@ -8935,36 +9008,6 @@
|
||||
"webpack": ">=5"
|
||||
}
|
||||
},
|
||||
"node_modules/babel-plugin-emotion": {
|
||||
"version": "10.2.2",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-emotion/-/babel-plugin-emotion-10.2.2.tgz",
|
||||
"integrity": "sha512-SMSkGoqTbTyUTDeuVuPIWifPdUGkTk1Kf9BWRiXIOIcuyMfsdp2EjeiiFvOzX8NOBvEh/ypKYvUh2rkgAJMCLA==",
|
||||
"dependencies": {
|
||||
"@babel/helper-module-imports": "^7.0.0",
|
||||
"@emotion/hash": "0.8.0",
|
||||
"@emotion/memoize": "0.7.4",
|
||||
"@emotion/serialize": "^0.11.16",
|
||||
"babel-plugin-macros": "^2.0.0",
|
||||
"babel-plugin-syntax-jsx": "^6.18.0",
|
||||
"convert-source-map": "^1.5.0",
|
||||
"escape-string-regexp": "^1.0.5",
|
||||
"find-root": "^1.1.0",
|
||||
"source-map": "^0.5.7"
|
||||
}
|
||||
},
|
||||
"node_modules/babel-plugin-emotion/node_modules/@emotion/memoize": {
|
||||
"version": "0.7.4",
|
||||
"resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.7.4.tgz",
|
||||
"integrity": "sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw=="
|
||||
},
|
||||
"node_modules/babel-plugin-emotion/node_modules/source-map": {
|
||||
"version": "0.5.7",
|
||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
|
||||
"integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/babel-plugin-formatjs": {
|
||||
"version": "10.5.1",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-formatjs/-/babel-plugin-formatjs-10.5.1.tgz",
|
||||
@@ -9040,16 +9083,6 @@
|
||||
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/babel-plugin-macros": {
|
||||
"version": "2.8.0",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-2.8.0.tgz",
|
||||
"integrity": "sha512-SEP5kJpfGYqYKpBrj5XU3ahw5p5GOHJ0U5ssOSQ/WBVdwkD2Dzlce95exQTs3jOVWPPKLBN2rlEWkCK7dSmLvg==",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.7.2",
|
||||
"cosmiconfig": "^6.0.0",
|
||||
"resolve": "^1.12.0"
|
||||
}
|
||||
},
|
||||
"node_modules/babel-plugin-polyfill-corejs2": {
|
||||
"version": "0.4.11",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.11.tgz",
|
||||
@@ -10901,21 +10934,6 @@
|
||||
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz",
|
||||
"integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ=="
|
||||
},
|
||||
"node_modules/cosmiconfig": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-6.0.0.tgz",
|
||||
"integrity": "sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg==",
|
||||
"dependencies": {
|
||||
"@types/parse-json": "^4.0.0",
|
||||
"import-fresh": "^3.1.0",
|
||||
"parse-json": "^5.0.0",
|
||||
"path-type": "^4.0.0",
|
||||
"yaml": "^1.7.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/country-list": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/country-list/-/country-list-2.2.0.tgz",
|
||||
@@ -12571,6 +12589,7 @@
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
|
||||
"integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=0.8.0"
|
||||
}
|
||||
@@ -23189,17 +23208,6 @@
|
||||
"resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.2.tgz",
|
||||
"integrity": "sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ=="
|
||||
},
|
||||
"node_modules/react-input-autosize": {
|
||||
"version": "2.2.2",
|
||||
"resolved": "https://registry.npmjs.org/react-input-autosize/-/react-input-autosize-2.2.2.tgz",
|
||||
"integrity": "sha512-jQJgYCA3S0j+cuOwzuCd1OjmBmnZLdqQdiLKRYrsMMzbjUrVDS5RvJUDwJqA7sKuksDuzFtm6hZGKFu7Mjk5aw==",
|
||||
"dependencies": {
|
||||
"prop-types": "^15.5.8"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^0.14.9 || ^15.3.0 || ^16.0.0-rc || ^16.0"
|
||||
}
|
||||
},
|
||||
"node_modules/react-intl": {
|
||||
"version": "6.6.2",
|
||||
"resolved": "https://registry.npmjs.org/react-intl/-/react-intl-6.6.2.tgz",
|
||||
|
||||
Ссылка в новой задаче
Block a user