Skip to content

Commit

Permalink
[Temp]: Rework how to add new Entities to the canvas
Browse files Browse the repository at this point in the history
  • Loading branch information
lordrip committed Apr 24, 2024
1 parent 7ab49c5 commit 22fc3b0
Show file tree
Hide file tree
Showing 28 changed files with 1,162 additions and 294 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,29 +3,39 @@ import { FunctionComponent, useContext } from 'react';
import { sourceSchemaConfig } from '../../../models/camel';
import { EntitiesContext } from '../../../providers/entities.provider';
import './ContextToolbar.scss';
import { DSLSelector } from './DSLSelector/DSLSelector';
import { FlowClipboard } from './FlowClipboard/FlowClipboard';
import { FlowExportImage } from './FlowExportImage/FlowExportImage';
import { NewFlow } from './FlowType/NewFlow';
import { FlowsMenu } from './Flows/FlowsMenu';
import { NewEntity } from './NewEntity/NewEntity';

export const ContextToolbar: FunctionComponent = () => {
const { currentSchemaType } = useContext(EntitiesContext)!;
const isMultipleRoutes = sourceSchemaConfig.config[currentSchemaType].multipleRoute;

return [
<ToolbarItem className="current-dsl-tag" key="toolbar-current-dsl">
<span data-testid="toolbar-current-dsl">{sourceSchemaConfig.config[currentSchemaType].name || 'None'}</span>
const toolbarItems: JSX.Element[] = [
<ToolbarItem key="toolbar-dsl-selector">
<DSLSelector />
</ToolbarItem>,
<ToolbarItem key="toolbar-flows-list">
<FlowsMenu />
</ToolbarItem>,
<ToolbarItem key="toolbar-new-route">
<NewFlow />
</ToolbarItem>,
];

if (isMultipleRoutes) {
toolbarItems.push(
<ToolbarItem key="toolbar-new-route">
<NewEntity />
</ToolbarItem>,
);
}

return toolbarItems.concat([
<ToolbarItem key="toolbar-clipboard">
<FlowClipboard />
</ToolbarItem>,
<ToolbarItem key={'toolbar-export-image'}>
<FlowExportImage />
</ToolbarItem>,
];
]);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { fireEvent, render } from '@testing-library/react';
import { ChangeDSLModal } from './ChangeDSLModal';

describe('ChangeDSLModal', () => {
it('should be hidden when isOpen is false', () => {
const wrapper = render(<ChangeDSLModal isOpen={false} onConfirm={jest.fn()} onCancel={jest.fn()} />);

expect(wrapper.queryByTestId('confirmation-modal')).not.toBeInTheDocument();
});

it('should be visible when isOpen is true', () => {
const wrapper = render(<ChangeDSLModal isOpen={true} onConfirm={jest.fn()} onCancel={jest.fn()} />);

expect(wrapper.queryByTestId('confirmation-modal')).toBeInTheDocument();
});

it('should call onConfirm when confirm button is clicked', () => {
const onConfirm = jest.fn();
const wrapper = render(<ChangeDSLModal isOpen={true} onConfirm={onConfirm} onCancel={jest.fn()} />);

fireEvent.click(wrapper.getByTestId('confirmation-modal-confirm'));

expect(onConfirm).toBeCalled();
});

it('should call onCancel when cancel button is clicked', () => {
const onCancel = jest.fn();
const wrapper = render(<ChangeDSLModal isOpen={true} onConfirm={jest.fn()} onCancel={onCancel} />);

fireEvent.click(wrapper.getByTestId('confirmation-modal-cancel'));

expect(onCancel).toBeCalled();
});

it('should call onCancel when close button is clicked', () => {
const onCancel = jest.fn();
const wrapper = render(<ChangeDSLModal isOpen={true} onConfirm={jest.fn()} onCancel={onCancel} />);

fireEvent.click(wrapper.getByLabelText('Close'));

expect(onCancel).toBeCalled();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { Button, Modal, ModalVariant } from '@patternfly/react-core';
import { FunctionComponent } from 'react';

interface ChangeDSLModalProps {
isOpen: boolean;
onConfirm: () => void;
onCancel: () => void;
}

export const ChangeDSLModal: FunctionComponent<ChangeDSLModalProps> = (props) => {
return (
<Modal
variant={ModalVariant.small}
title="Warning"
data-testid="confirmation-modal"
titleIconVariant="warning"
onClose={props.onCancel}
actions={[
<Button key="confirm" variant="primary" data-testid="confirmation-modal-confirm" onClick={props.onConfirm}>
Confirm
</Button>,
<Button key="cancel" variant="link" data-testid="confirmation-modal-cancel" onClick={props.onCancel}>
Cancel
</Button>,
]}
isOpen={props.isOpen}
>
<p>
This will remove any existing integration and you will lose your current work. Are you sure you would like to
proceed?
</p>
</Modal>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import { act, fireEvent, render } from '@testing-library/react';
import { EntitiesContextResult } from '../../../../hooks';
import { KaotoSchemaDefinition } from '../../../../models';
import { SourceSchemaType, sourceSchemaConfig } from '../../../../models/camel';
import { EntitiesContext } from '../../../../providers/entities.provider';
import { SourceCodeApiContext } from '../../../../providers/source-code.provider';
import { DSLSelector } from './DSLSelector';

describe('DSLSelector.tsx', () => {
const config = sourceSchemaConfig;
config.config[SourceSchemaType.Integration].schema = {
schema: { name: 'Integration', description: 'desc' } as KaotoSchemaDefinition['schema'],
} as KaotoSchemaDefinition;
config.config[SourceSchemaType.Pipe].schema = {
schema: { name: 'Pipe', description: 'desc' } as KaotoSchemaDefinition['schema'],
} as KaotoSchemaDefinition;
config.config[SourceSchemaType.Kamelet].schema = {
schema: { name: 'Kamelet', description: 'desc' } as KaotoSchemaDefinition['schema'],
} as KaotoSchemaDefinition;
config.config[SourceSchemaType.KameletBinding].schema = {
name: 'kameletBinding',
schema: { description: 'desc' },
} as KaotoSchemaDefinition;
config.config[SourceSchemaType.Route].schema = {
schema: { name: 'route', description: 'desc' } as KaotoSchemaDefinition['schema'],
} as KaotoSchemaDefinition;

const renderWithContext = () => {
return render(
<SourceCodeApiContext.Provider
value={{
setCodeAndNotify: jest.fn(),
}}
>
<EntitiesContext.Provider
value={
{
currentSchemaType: SourceSchemaType.Integration,
} as unknown as EntitiesContextResult
}
>
<DSLSelector />
</EntitiesContext.Provider>
</SourceCodeApiContext.Provider>,
);
};

it('should render all of the types', async () => {
const wrapper = renderWithContext();
const trigger = await wrapper.findByTestId('dsl-list-dropdown');

/** Open Select */
act(() => {
fireEvent.click(trigger);
});

for (const name of ['Pipe', 'Camel Route']) {
const element = await wrapper.findByText(name);
expect(element).toBeInTheDocument();
}
});

it('should warn the user when adding a different type of flow', async () => {
const wrapper = renderWithContext();
const trigger = await wrapper.findByTestId('dsl-list-dropdown');

/** Open Select */
act(() => {
fireEvent.click(trigger);
});

/** Select an option */
act(() => {
const element = wrapper.getByText('Pipe');
fireEvent.click(element);
});

const modal = await wrapper.findByTestId('confirmation-modal');
expect(modal).toBeInTheDocument();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { FunctionComponent, PropsWithChildren, useCallback, useContext, useState } from 'react';
import { SourceSchemaType } from '../../../../models/camel';
import { FlowTemplateService } from '../../../../models/visualization/flows/support/flow-templates-service';
import { SourceCodeApiContext } from '../../../../providers';
import { ChangeDSLModal } from './ChangeDSLModal/ChangeDSLModal';
import { DSLSelectorToggle } from './DSLSelectorToggle/DSLSelectorToggle';

export const DSLSelector: FunctionComponent<PropsWithChildren> = () => {
const sourceCodeContextApi = useContext(SourceCodeApiContext);
const [isConfirmationModalOpen, setIsConfirmationModalOpen] = useState(false);
const [proposedFlowType, setProposedFlowType] = useState<SourceSchemaType>();

const checkBeforeAddNewFlow = useCallback((flowType: SourceSchemaType) => {
/**
* If it is not the same DSL, this operation might result in
* removing the existing flows, so then we warn the user first
*/
setProposedFlowType(flowType);
setIsConfirmationModalOpen(true);
}, []);

const onConfirm = useCallback(() => {
if (proposedFlowType) {
sourceCodeContextApi.setCodeAndNotify(FlowTemplateService.getFlowYamlTemplate(proposedFlowType));
setIsConfirmationModalOpen(false);
}
}, [proposedFlowType, sourceCodeContextApi]);

const onCancel = useCallback(() => {
setIsConfirmationModalOpen(false);
}, []);

return (
<>
<DSLSelectorToggle onSelect={checkBeforeAddNewFlow} />
<ChangeDSLModal isOpen={isConfirmationModalOpen} onConfirm={onConfirm} onCancel={onCancel} />
</>
);
};

0 comments on commit 22fc3b0

Please sign in to comment.