diff --git a/src/billing/Members/Members.test.tsx b/src/billing/Members/Members.test.tsx index f2d94da381..eb6a05b5ef 100644 --- a/src/billing/Members/Members.test.tsx +++ b/src/billing/Members/Members.test.tsx @@ -7,6 +7,7 @@ import { EmailSelect } from 'src/groups/Members/EmailSelect'; import { Member } from 'src/groups/Members/MemberTable'; import { Billing, BillingContract } from 'src/libs/ajax/billing/Billing'; import { Groups, GroupsContract } from 'src/libs/ajax/Groups'; +import { Workspaces, WorkspacesAjaxContract } from 'src/libs/ajax/workspaces/Workspaces'; import { asMockedFn, MockedFn, partial, renderWithAppContexts } from 'src/testing/test-utils'; jest.mock('src/libs/ajax/billing/Billing'); @@ -84,6 +85,11 @@ describe('Members', () => { const addProjectUsers: MockedFn = jest.fn(); asMockedFn(Billing).mockReturnValue(partial({ addProjectUsers })); // Next 2 mocks are needed for suggestions in the NewUserModal. + asMockedFn(Workspaces).mockReturnValue( + partial({ + getShareLog: jest.fn(async () => []), + }) + ); asMockedFn(Groups).mockReturnValue( partial({ list: jest.fn(async () => []), @@ -95,11 +101,6 @@ describe('Members', () => { const defaultProps = { label: 'User emails', placeholder: 'Test emails', - isMulti: true, - isClearable: true, - isSearchable: true, - options: ['test-user@company.com', 'test-user2@company.com'], - emails: ['test-user@company.com'], setEmails: jest.fn(), }; diff --git a/src/groups/Members/EmailSelect.test.tsx b/src/groups/Members/EmailSelect.test.tsx index fe30af9d96..50b7398b56 100644 --- a/src/groups/Members/EmailSelect.test.tsx +++ b/src/groups/Members/EmailSelect.test.tsx @@ -8,11 +8,6 @@ describe('EmailSelect', () => { const defaultProps = { label: 'User emails', placeholder: 'Type or select user emails', - isMulti: true, - isClearable: true, - isSearchable: true, - options: ['test1@example.com', 'test2@example.com'], - emails: ['test1@example.com'], setEmails: jest.fn(), }; @@ -29,67 +24,28 @@ describe('EmailSelect', () => { expect(label).toBeInTheDocument(); }); - it('calls setEmails when an email is selected', () => { + it('calls setEmails when an email is entered', () => { // Arrange render(); const input = screen.getByLabelText(defaultProps.placeholder); // Act fireEvent.change(input, { target: { value: 'test2@example.com' } }); - fireEvent.keyDown(input, { key: 'Enter', code: 'Enter' }); + // fireEvent.keyDown(input, { key: 'Enter', code: 'Enter' }); // Assert - expect(defaultProps.setEmails).toHaveBeenCalledWith(['test1@example.com', 'test2@example.com']); + expect(defaultProps.setEmails).toHaveBeenCalledWith(['test2@example.com']); }); - it('calls setEmails when an email is removed', () => { + it('divides emails by comma', () => { // Arrange render(); const input = screen.getByLabelText(defaultProps.placeholder); // Act - fireEvent.keyDown(input, { key: 'Backspace', code: 'Backspace' }); + fireEvent.change(input, { target: { value: 'test2@example.com,test1@example.com' } }); // Assert - expect(defaultProps.setEmails).toHaveBeenCalledWith([]); - }); - - it('renders the correct number of selected options', () => { - // Arrange - render(); - const input = screen.getByLabelText(defaultProps.placeholder); - - // Act - fireEvent.focus(input); - const options = screen.getAllByRole('button'); // Each selected option has a remove button - - // Assert - expect(options).toHaveLength(defaultProps.emails.length); - }); - - it('updates searchValue on input change', () => { - // Arrange - render(); - const input = screen.getByLabelText(defaultProps.placeholder); - - // Act - fireEvent.change(input, { target: { value: 'newemail@example.com' } }); - - // Assert - // @ts-ignore - expect(input.value).toBe('newemail@example.com'); - }); - - it('saves searchValue to emails on blur', () => { - // Arrange - render(); - const input = screen.getByLabelText(defaultProps.placeholder); - - // Act - fireEvent.change(input, { target: { value: 'newemail@example.com' } }); - fireEvent.blur(input); - - // Assert - expect(defaultProps.setEmails).toHaveBeenCalledWith(['test1@example.com', 'newemail@example.com']); + expect(defaultProps.setEmails).toHaveBeenCalledWith(['test2@example.com', 'test1@example.com']); }); }); diff --git a/src/groups/Members/EmailSelect.tsx b/src/groups/Members/EmailSelect.tsx index 0f114d7104..24007ce693 100644 --- a/src/groups/Members/EmailSelect.tsx +++ b/src/groups/Members/EmailSelect.tsx @@ -1,59 +1,30 @@ -import { CreatableSelect, useUniqueId } from '@terra-ui-packages/components'; +import { useUniqueId } from '@terra-ui-packages/components'; import _ from 'lodash/fp'; -import React, { useState } from 'react'; +import React from 'react'; +import { TextInput } from 'src/components/input'; import { FormLabel } from 'src/libs/forms'; interface EmailSelectProps { label?: string; placeholder?: string; - isMulti?: boolean; - isClearable?: boolean; - isSearchable?: boolean; - options: string[]; - emails: string[]; setEmails: (values: string[]) => void; } export const EmailSelect: React.FC = ({ label = 'User emails', - placeholder = 'Type or select user emails', - isMulti = true, - isClearable = true, - isSearchable = true, - options, - emails, + placeholder = 'Type user emails separated by commas', setEmails, }) => { - const [searchValue, setSearchValue] = useState(''); - const emailInputId = useUniqueId(); - const emptySearchValue = (searchValue: string) => searchValue === ''; - const addSelectedOptions = (options: string[]) => { - const selectedOptions: string[] = _.flatMap( - (option) => - option - .split(',') - .map((email) => email.trim()) - .filter((email) => email !== ''), - options - ); + const addSelectedOptions = (emails: string) => { + const selectedOptions: string[] = emails + .split(',') + .map((email) => email.trim()) + .filter((email) => email !== ''); const newEmail: string | undefined = _.find((email: string) => !emails.includes(email), selectedOptions); if (newEmail || newEmail === undefined) { setEmails(selectedOptions); } - setSearchValue(''); - }; - - const handleOnInputChange = (inputValue: any) => { - !emptySearchValue(inputValue) && setSearchValue(inputValue); - }; - - const handleOnBlur = () => { - !emptySearchValue(searchValue) && addSelectedOptions([...emails, searchValue]); - }; - - const handleOnChange = (options: Array<{ value: string; label: string }>) => { - addSelectedOptions(_.map((option) => option.value, options)); }; return ( @@ -61,20 +32,12 @@ export const EmailSelect: React.FC = ({ {label} - ({ value, label: value }), emails)} - options={_.map((value: string) => ({ value, label: value }), options)} - onInputChange={handleOnInputChange} - onBlur={handleOnBlur} - onChange={handleOnChange} + onChange={addSelectedOptions} height={200} - noOptionsMessage={() => null} /> ); diff --git a/src/groups/Members/NewMemberModal.test.tsx b/src/groups/Members/NewMemberModal.test.tsx index e65bff2314..6becb014c3 100644 --- a/src/groups/Members/NewMemberModal.test.tsx +++ b/src/groups/Members/NewMemberModal.test.tsx @@ -66,7 +66,7 @@ describe('NewMemberModal', () => { it('handles user input for emails and roles', async () => { // Arrange render(); - const emailInput = screen.getByLabelText('Type or select user emails'); + const emailInput = screen.getByLabelText('Type user emails separated by commas'); const roleSelect = screen.getByLabelText('Select Role'); // Act @@ -87,13 +87,13 @@ describe('NewMemberModal', () => { it('submits valid data and calls addFunction', async () => { // Arrange render(); - const emailInput = screen.getByLabelText('Type or select user emails'); + const emailInput = screen.getByLabelText('Type user emails separated by commas'); const addButton = screen.getByText('Add Users'); const userEmails = ['test1@example.com', 'test2@example.com']; const userRole = 'Member'; // Act - fireEvent.change(emailInput, { target: { value: userEmails } }); + fireEvent.change(emailInput, { target: { value: userEmails.join(',') } }); fireEvent.keyDown(emailInput, { key: 'Enter', code: 'Enter' }); fireEvent.click(addButton); @@ -114,7 +114,7 @@ describe('NewMemberModal', () => { render(); - const emailInput = screen.getByLabelText('Type or select user emails'); + const emailInput = screen.getByLabelText('Type user emails separated by commas'); const addButton = screen.getByText('Add Users'); fireEvent.change(emailInput, { target: { value: 'test@example.com' } }); diff --git a/src/groups/Members/NewMemberModal.tsx b/src/groups/Members/NewMemberModal.tsx index 7c0a3d1767..bedbb2064e 100644 --- a/src/groups/Members/NewMemberModal.tsx +++ b/src/groups/Members/NewMemberModal.tsx @@ -114,7 +114,7 @@ export const NewMemberModal = (props: NewMemberModalProps) => { >
- +
diff --git a/src/workspaces/ShareWorkspaceModal/ShareWorkspaceModal.tsx b/src/workspaces/ShareWorkspaceModal/ShareWorkspaceModal.tsx index f4d54dc570..6d2205d92d 100644 --- a/src/workspaces/ShareWorkspaceModal/ShareWorkspaceModal.tsx +++ b/src/workspaces/ShareWorkspaceModal/ShareWorkspaceModal.tsx @@ -137,12 +137,7 @@ const ShareWorkspaceModal: React.FC = (props: ShareWor
- +