From 5959ccde8d9275902bd0f6c8c95c179903d4978c Mon Sep 17 00:00:00 2001 From: emilys314 Date: Wed, 25 Sep 2024 16:15:49 -0400 Subject: [PATCH] Connection modal typeahead enhancements --- .../connectionTypes/ConnectionTypeForm.tsx | 86 ++++++++++++++----- .../__tests__/ManageConnectionsModal.spec.tsx | 14 +-- 2 files changed, 73 insertions(+), 27 deletions(-) diff --git a/frontend/src/concepts/connectionTypes/ConnectionTypeForm.tsx b/frontend/src/concepts/connectionTypes/ConnectionTypeForm.tsx index 5875fa22d5..939fa9ce70 100644 --- a/frontend/src/concepts/connectionTypes/ConnectionTypeForm.tsx +++ b/frontend/src/concepts/connectionTypes/ConnectionTypeForm.tsx @@ -1,11 +1,21 @@ import * as React from 'react'; -import { Form, FormGroup, FormSection, MenuToggleStatus, Title } from '@patternfly/react-core'; +import { + Flex, + FlexItem, + Form, + FormGroup, + FormSection, + MenuToggleStatus, + Title, + Truncate, +} from '@patternfly/react-core'; import ConnectionTypeFormFields from '~/concepts/connectionTypes/fields/ConnectionTypeFormFields'; import { ConnectionTypeConfigMapObj, ConnectionTypeValueType, } from '~/concepts/connectionTypes/types'; import { + getDescriptionFromK8sResource, getDisplayNameFromK8sResource, getResourceNameFromK8sResource, } from '~/concepts/k8s/utils'; @@ -17,6 +27,48 @@ import { } from '~/concepts/k8s/K8sNameDescriptionField/types'; import { ConnectionTypeDetailsHelperText } from './ConnectionTypeDetailsHelperText'; +const getConnectionTypeSelectOptions = ( + isPreview: boolean, + selectedConnectionType?: ConnectionTypeConfigMapObj, + connectionTypes?: ConnectionTypeConfigMapObj[], +): TypeaheadSelectOption[] => { + if (isPreview && selectedConnectionType?.metadata.annotations?.['openshift.io/display-name']) { + return [ + { + value: '', + content: selectedConnectionType.metadata.annotations['openshift.io/display-name'], + isSelected: true, + }, + ]; + } + if (!isPreview && connectionTypes) { + return connectionTypes.map((t) => ({ + value: getResourceNameFromK8sResource(t), + content: getDisplayNameFromK8sResource(t), + description: ( + + {getDescriptionFromK8sResource(t) && ( + + + + )} + {t.data?.category?.length && ( + + + + )} + + ), + data: `${getDescriptionFromK8sResource(t)} ${t.data?.category?.join(' ')}`, + isSelected: + !!selectedConnectionType && + getResourceNameFromK8sResource(t) === + getResourceNameFromK8sResource(selectedConnectionType), + })); + } + return []; +}; + type Props = Pick< React.ComponentProps, 'onChange' | 'onValidate' @@ -45,25 +97,10 @@ const ConnectionTypeForm: React.FC = ({ onValidate, disableTypeSelection, }) => { - const options: TypeaheadSelectOption[] = React.useMemo(() => { - if (isPreview && connectionType?.metadata.annotations?.['openshift.io/display-name']) { - return [ - { - value: '', - content: connectionType.metadata.annotations['openshift.io/display-name'], - isSelected: true, - }, - ]; - } - if (!isPreview && connectionTypes) { - return connectionTypes.map((t) => ({ - value: getResourceNameFromK8sResource(t), - content: getDisplayNameFromK8sResource(t), - isSelected: t.metadata.name === connectionType?.metadata.name, - })); - } - return []; - }, [isPreview, connectionType?.metadata, connectionTypes]); + const options: TypeaheadSelectOption[] = React.useMemo( + () => getConnectionTypeSelectOptions(isPreview, connectionType, connectionTypes), + [isPreview, connectionType, connectionTypes], + ); return (
@@ -86,6 +123,15 @@ const ConnectionTypeForm: React.FC = ({ ? { status: MenuToggleStatus.danger } : undefined } + isScrollable + popperProps={{ maxWidth: 'trigger' }} + filterFunction={(filterValue: string, filterOptions: TypeaheadSelectOption[]) => + filterOptions.filter( + (o) => + String(o.content).toLowerCase().includes(filterValue.toLowerCase()) || + String(o.data).toLowerCase().includes(filterValue.toLowerCase()), + ) + } /> {connectionType && ( diff --git a/frontend/src/pages/projects/screens/detail/connections/__tests__/ManageConnectionsModal.spec.tsx b/frontend/src/pages/projects/screens/detail/connections/__tests__/ManageConnectionsModal.spec.tsx index ff29e46f52..3c02ac2e4f 100644 --- a/frontend/src/pages/projects/screens/detail/connections/__tests__/ManageConnectionsModal.spec.tsx +++ b/frontend/src/pages/projects/screens/detail/connections/__tests__/ManageConnectionsModal.spec.tsx @@ -87,12 +87,12 @@ describe('Add connection modal', () => { await act(async () => { screen.getByRole('button', { name: 'Typeahead menu toggle' }).click(); }); - expect(screen.getByRole('option', { name: 'type one' })).toBeTruthy(); - expect(screen.getByRole('option', { name: 'type two' })).toBeTruthy(); - expect(screen.queryByRole('option', { name: 'type three disabled' })).toBeFalsy(); + expect(screen.getByRole('option', { name: /type one/ })).toBeTruthy(); + expect(screen.getByRole('option', { name: /type two/ })).toBeTruthy(); + expect(screen.queryByRole('option', { name: /type three disabled/ })).toBeFalsy(); await act(async () => { - screen.getByRole('option', { name: 'type one' }).click(); + screen.getByRole('option', { name: /type one/ }).click(); }); expect(screen.getByRole('combobox')).toHaveValue('type one'); expect(screen.getByRole('textbox', { name: 'Connection name' })).toBeVisible(); @@ -294,7 +294,7 @@ describe('Add connection modal', () => { screen.getByRole('button', { name: 'Typeahead menu toggle' }).click(); }); await act(async () => { - screen.getByRole('option', { name: 'type one' }).click(); + screen.getByRole('option', { name: /type one/ }).click(); }); await act(async () => { fireEvent.change(screen.getByRole('textbox', { name: 'Connection name' }), { @@ -319,7 +319,7 @@ describe('Add connection modal', () => { screen.getByRole('button', { name: 'Typeahead menu toggle' }).click(); }); await act(async () => { - screen.getByRole('option', { name: 'type two' }).click(); + screen.getByRole('option', { name: /type two/ }).click(); }); expect(screen.getByRole('textbox', { name: 'Connection name' })).toHaveValue( 'connection one name', @@ -333,7 +333,7 @@ describe('Add connection modal', () => { screen.getByRole('button', { name: 'Typeahead menu toggle' }).click(); }); await act(async () => { - screen.getByRole('option', { name: 'type one' }).click(); + screen.getByRole('option', { name: /type one/ }).click(); }); expect(screen.getByRole('textbox', { name: 'Connection name' })).toHaveValue( 'connection one name',