Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(CanvasForm): Improvements over the ParametersField component #1489

Merged
merged 1 commit into from
Oct 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
14 changes: 11 additions & 3 deletions packages/ui-tests/stories/canvas/CanvasSideBar.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {
CamelRouteVisualEntity,
CanvasFormTabsContext,
CanvasNode,
CanvasSideBar,
IVisualizationNode,
Expand Down Expand Up @@ -99,9 +100,16 @@ const Template: StoryFn<typeof CanvasSideBar> = (args) => {
const [isModalOpen, setIsModalOpen] = useState(false);
const handleClose = () => setIsModalOpen(!isModalOpen);
return (
<VisibleFlowsProvider>
<CanvasSideBar {...args} onClose={handleClose} />
</VisibleFlowsProvider>
<CanvasFormTabsContext.Provider
value={{
selectedTab: 'All',
onTabChange: () => {},
}}
>
<VisibleFlowsProvider>
<CanvasSideBar {...args} onClose={handleClose} />
</VisibleFlowsProvider>
</CanvasFormTabsContext.Provider>
);
};

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