Skip to content

Commit

Permalink
fix(PropertiesField): Reduce padding and start with expandable open
Browse files Browse the repository at this point in the history
Currently, the `PropertiesField` component overflows from the containing
`Form`.

This commit:
* Reduces its padding
* Changes the containing `Td` so it can limit the overflow
* Extracts the `PropertiesFieldEmpty` state component
* Add a few missing tests

fix: KaotoIO#1473
  • Loading branch information
lordrip committed Oct 1, 2024
1 parent c36f314 commit 3ed2df1
Show file tree
Hide file tree
Showing 28 changed files with 2,129 additions and 296 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ describe('Tests for side panel step filtering', () => {

cy.selectFormTab('Required');

cy.get('.pf-v5-c-alert__title').should('contain', 'No Required Field Found');
cy.get('.pf-v5-c-alert__title').should('contain', 'No Required fields found');
});

it('Side panel to retain user specified fields filter', () => {
Expand Down
40 changes: 40 additions & 0 deletions packages/ui/src/components/Form/CustomAutoFields.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { act, render } from '@testing-library/react';
import { KaotoSchemaDefinition } from '../../models';
import { CanvasFormTabsProvider } from '../../providers';
import { UniformsWrapper } from '../../stubs/TestUniformsWrapper';
import { TimerComponentSchema } from '../../stubs/timer.component.schema';
import { CustomAutoFields } from './CustomAutoFields';

describe('CustomAutoFields', () => {
it('renders `AutoFields` for common fields', () => {
let wrapper: ReturnType<typeof render> | undefined;

act(() => {
wrapper = render(
<CanvasFormTabsProvider>
<UniformsWrapper model={{}} schema={TimerComponentSchema as KaotoSchemaDefinition['schema']}>
<CustomAutoFields />
</UniformsWrapper>
</CanvasFormTabsProvider>,
);
});

expect(wrapper?.asFragment()).toMatchSnapshot();
});

it('render `NoFieldFound` when there are no fields', () => {
let wrapper: ReturnType<typeof render> | undefined;

act(() => {
wrapper = render(
<CanvasFormTabsProvider>
<UniformsWrapper model={{}} schema={{ type: 'object' } as KaotoSchemaDefinition['schema']}>
<CustomAutoFields />
</UniformsWrapper>
</CanvasFormTabsProvider>,
);
});

expect(wrapper?.asFragment()).toMatchSnapshot();
});
});
4 changes: 2 additions & 2 deletions packages/ui/src/components/Form/CustomAutoFields.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export function CustomAutoFields({
const { schema } = useForm();
const rootField = schema.getField('');
const { filteredFieldText, isGroupExpanded } = useContext(FilteredFieldContext);
const { selectedTab } = useContext(CanvasFormTabsContext);
const canvasFormTabsContext = useContext(CanvasFormTabsContext);

/** Special handling for oneOf schemas */
if (Array.isArray((rootField as KaotoSchemaDefinition['schema']).oneOf)) {
Expand All @@ -45,7 +45,7 @@ export function CustomAutoFields({
const propertiesArray = getFieldGroups(actualFieldsSchema);

if (
selectedTab !== 'All' &&
canvasFormTabsContext?.selectedTab !== 'All' &&
propertiesArray.common.length === 0 &&
Object.keys(propertiesArray.groups).length === 0
) {
Expand Down
44 changes: 44 additions & 0 deletions packages/ui/src/components/Form/NoFieldFound.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { fireEvent, render, screen } from '@testing-library/react';
import { CanvasFormTabsContext, CanvasFormTabsContextResult } from '../../providers';
import { NoFieldFound } from './NoFieldFound';

describe('NoFieldFound Component', () => {
it('should render null if canvasFormTabsContext is not provided', () => {
const { container } = render(<NoFieldFound />);
expect(container.firstChild).toBeNull();
});

it('should render the alert with the correct tab name', () => {
const mockContextValue: CanvasFormTabsContextResult = {
selectedTab: 'Required',
onTabChange: jest.fn(),
};

render(
<CanvasFormTabsContext.Provider value={mockContextValue}>
<NoFieldFound />
</CanvasFormTabsContext.Provider>,
);

expect(screen.getByTestId('no-field-found')).toBeInTheDocument();
expect(screen.getByText('No Required fields found')).toBeInTheDocument();
});

it('should call onTabChange when the button is clicked', () => {
const mockContextValue: CanvasFormTabsContextResult = {
selectedTab: 'Required',
onTabChange: jest.fn(),
};

render(
<CanvasFormTabsContext.Provider value={mockContextValue}>
<NoFieldFound />
</CanvasFormTabsContext.Provider>,
);

const button = screen.getByRole('button', { name: /All/i });
fireEvent.click(button);

expect(mockContextValue.onTabChange).toHaveBeenCalled();
});
});
13 changes: 9 additions & 4 deletions packages/ui/src/components/Form/NoFieldFound.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,18 @@ import { FunctionComponent, useContext } from 'react';
import { CanvasFormTabsContext } from '../../providers';

export const NoFieldFound: FunctionComponent = () => {
const { selectedTab, onTabChange } = useContext(CanvasFormTabsContext);
const canvasFormTabsContext = useContext(CanvasFormTabsContext);

if (!canvasFormTabsContext) {
return null;
}

return (
<Card>
<Card data-testid="no-field-found">
<CardBody>
<Alert variant="info" title={`No ${selectedTab} Field Found`}>
<Alert variant="info" title={`No ${canvasFormTabsContext.selectedTab} fields found`}>
No field found matching this criteria. Please switch to the{' '}
<Button id="All" onClick={(e) => onTabChange(e, true)} variant="link" isInline>
<Button id="All" onClick={canvasFormTabsContext.onTabChange} variant="link" isInline>
<b>All</b>
</Button>{' '}
tab.
Expand Down
29 changes: 1 addition & 28 deletions packages/ui/src/components/Form/OneOf/OneOfField.test.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import { AutoForm } from '@kaoto-next/uniforms-patternfly';
import { act, fireEvent, render } from '@testing-library/react';
import { FunctionComponent, PropsWithChildren, useEffect, useRef, useState } from 'react';
import { KaotoSchemaDefinition } from '../../../models/kaoto-schema';
import { SchemaBridgeContext } from '../../../providers/schema-bridge.provider';
import { UniformsWrapper } from '../../../stubs/TestUniformsWrapper';
import { SchemaService } from '../schema.service';
import { OneOfField } from './OneOfField';

Expand Down Expand Up @@ -88,28 +86,3 @@ describe('OneOfField', () => {
expect(nameField).toHaveValue('');
});
});

const UniformsWrapper: FunctionComponent<
PropsWithChildren<{
model: Record<string, unknown>;
schema: KaotoSchemaDefinition['schema'];
}>
> = (props) => {
const schemaBridge = new SchemaService().getSchemaBridge(props.schema);
const divRef = useRef<HTMLDivElement>(null);
const [, setLastRenderTimestamp] = useState<number>(-1);

useEffect(() => {
/** Force re-render to update the divRef */
setLastRenderTimestamp(Date.now());
}, []);

return (
<SchemaBridgeContext.Provider value={{ schemaBridge, parentRef: divRef }}>
<AutoForm model={props.model} schema={schemaBridge}>
{props.children}
</AutoForm>
<div ref={divRef} />
</SchemaBridgeContext.Provider>
);
};
Loading

0 comments on commit 3ed2df1

Please sign in to comment.