Skip to content

Commit

Permalink
feat(form): Introduce a 'User Modified' from section
Browse files Browse the repository at this point in the history
  • Loading branch information
shivamG640 committed Jul 24, 2024
1 parent 6872f16 commit 71e64c4
Show file tree
Hide file tree
Showing 20 changed files with 1,389 additions and 432 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { DataFormatEditor, MetadataEditor } from '@kaoto/kaoto';
import { DataFormatEditor, MetadataEditor, FormTabsModes } from '@kaoto/kaoto';
import {
CanvasNode,
CatalogLoaderProvider,
Expand Down Expand Up @@ -63,4 +63,5 @@ const Template: StoryFn<typeof MetadataEditor> = (args: CanvasNode) => {
export const Default = Template.bind({});
Default.args = {
selectedNode: mockNode,
formMode: FormTabsModes.ALL_FIELDS,
};
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
SchemasLoaderProvider,
StepExpressionEditor,
VisualComponentSchema,
FormTabsModes,
} from '@kaoto/kaoto/testing';
import { Meta, StoryFn } from '@storybook/react';

Expand Down Expand Up @@ -63,4 +64,5 @@ const Template: StoryFn<typeof MetadataEditor> = (args: CanvasNode) => {
export const Default = Template.bind({});
Default.args = {
selectedNode: mockNode,
formMode: FormTabsModes.ALL_FIELDS,
};
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { getFirstCatalogMap } from '../../../stubs/test-load-catalog';
import { MetadataEditor } from '../../MetadataEditor';
import { CanvasNode } from '../../Visualization/Canvas/canvas.models';
import { DataFormatEditor } from './DataFormatEditor';
import { FormTabsModes } from '../../Visualization/Canvas/canvasformtabs.modes';

describe('DataFormatEditor', () => {
let mockNode: CanvasNode;
Expand Down Expand Up @@ -45,8 +46,56 @@ describe('DataFormatEditor', () => {
};
});

it('should not render', () => {
render(<DataFormatEditor selectedNode={mockNode} formMode={FormTabsModes.USER_MODIFIED} />);
const buttons = screen.queryAllByRole('button', { name: 'Typeahead menu toggle' });
expect(buttons).toHaveLength(0);
});

it('should render with only the user updated fields', () => {
const visualComponentSchema: VisualComponentSchema = {
title: 'My Node',
schema: {
type: 'object',
properties: {
name: {
type: 'string',
},
},
} as unknown as KaotoSchemaDefinition['schema'],
definition: {
name: 'my node',
asn1: {
id: 'test',
},
},
};

mockNode = {
id: '1',
type: 'node',
data: {
vizNode: {
getComponentSchema: () => visualComponentSchema,
updateModel: (_value: unknown) => {},
} as IVisualizationNode,
},
};
render(<DataFormatEditor selectedNode={mockNode} formMode={FormTabsModes.USER_MODIFIED} />);
const buttons = screen.queryAllByRole('button', { name: 'Typeahead menu toggle' });
expect(buttons).toHaveLength(1);

const inputElement = screen.getAllByRole('combobox')[0];
expect(inputElement).toHaveValue('ASN.1 File');

const inputIdModifiedTabElement = screen
.queryAllByRole('textbox')
.filter((textbox) => textbox.getAttribute('label') === 'Id');
expect(inputIdModifiedTabElement).toHaveLength(1);
});

it('should render', async () => {
render(<DataFormatEditor selectedNode={mockNode} />);
render(<DataFormatEditor selectedNode={mockNode} formMode={FormTabsModes.ALL_FIELDS} />);
const buttons = screen.getAllByRole('button', { name: 'Typeahead menu toggle' });
await act(async () => {
fireEvent.click(buttons[0]);
Expand All @@ -58,7 +107,7 @@ describe('DataFormatEditor', () => {
});

it('should filter candidates with a text input', async () => {
render(<DataFormatEditor selectedNode={mockNode} />);
render(<DataFormatEditor selectedNode={mockNode} formMode={FormTabsModes.ALL_FIELDS} />);
const buttons = screen.getAllByRole('button', { name: 'Typeahead menu toggle' });
await act(async () => {
fireEvent.click(buttons[0]);
Expand All @@ -74,7 +123,7 @@ describe('DataFormatEditor', () => {
});

it('should clear filter and close the dropdown with close button', async () => {
render(<DataFormatEditor selectedNode={mockNode} />);
render(<DataFormatEditor selectedNode={mockNode} formMode={FormTabsModes.ALL_FIELDS} />);
const buttons = screen.getAllByRole('button', { name: 'Typeahead menu toggle' });
await act(async () => {
fireEvent.click(buttons[0]);
Expand Down
21 changes: 19 additions & 2 deletions packages/ui/src/components/Form/dataFormat/DataFormatEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,12 @@ import { CanvasNode } from '../../Visualization/Canvas/canvas.models';
import './DataFormatEditor.scss';
import { DataFormatService } from './dataformat.service';
import { TypeaheadEditor } from '../customField/TypeaheadEditor';
import { getSerializedModel } from '../../../utils';
import { getSerializedModel, getUserUpdatedPropertiesSchema, isDefined } from '../../../utils';
import { FormTabsModes } from '../../Visualization/Canvas/canvasformtabs.modes';

interface DataFormatEditorProps {
selectedNode: CanvasNode;
formMode: FormTabsModes;
}

export const DataFormatEditor: FunctionComponent<DataFormatEditorProps> = (props) => {
Expand Down Expand Up @@ -58,6 +60,14 @@ export const DataFormatEditor: FunctionComponent<DataFormatEditorProps> = (props
return DataFormatService.getDataFormatSchema(dataFormat);
}, [dataFormat]);

const processedSchema = useMemo(() => {
if (props.formMode === FormTabsModes.ALL_FIELDS) return dataFormatSchema;
return {
...dataFormatSchema,
properties: getUserUpdatedPropertiesSchema(dataFormatSchema?.properties ?? {}, dataFormatModel ?? {}),
};
}, [props.formMode, dataFormat]);

const handleOnChange = useCallback(
(
selectedDataFormatOption: { name: string; title: string } | undefined,
Expand All @@ -78,6 +88,13 @@ export const DataFormatEditor: FunctionComponent<DataFormatEditorProps> = (props
[entitiesContext, dataFormatCatalogMap, props.selectedNode.data?.vizNode],
);

const showEditor = useMemo(() => {
if (props.formMode === FormTabsModes.ALL_FIELDS) return true;
return props.formMode === FormTabsModes.USER_MODIFIED && isDefined(selectedDataFormatOption);
}, [props.formMode]);

if (!showEditor) return null;

return (
<div className="dataformat-metadata-editor">
<Card isCompact={true} isExpanded={isExpanded} className="dataformat-metadata-editor-card">
Expand All @@ -91,7 +108,7 @@ export const DataFormatEditor: FunctionComponent<DataFormatEditorProps> = (props
title="dataformat"
selected={selectedDataFormatOption}
selectedModel={dataFormatModel}
selectedSchema={dataFormatSchema}
selectedSchema={processedSchema}
selectionOnChange={handleOnChange}
/>
</CardBody>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { getFirstCatalogMap } from '../../../stubs/test-load-catalog';
import { MetadataEditor } from '../../MetadataEditor';
import { CanvasNode } from '../../Visualization/Canvas/canvas.models';
import { LoadBalancerEditor } from './LoadBalancerEditor';
import { FormTabsModes } from '../../Visualization/Canvas/canvasformtabs.modes';

describe('LoadBalancerEditor', () => {
let mockNode: CanvasNode;
Expand Down Expand Up @@ -46,8 +47,56 @@ describe('LoadBalancerEditor', () => {
};
});

it('should not render', () => {
render(<LoadBalancerEditor selectedNode={mockNode} formMode={FormTabsModes.USER_MODIFIED} />);
const buttons = screen.queryAllByRole('button', { name: 'Typeahead menu toggle' });
expect(buttons).toHaveLength(0);
});

it('should render with only the user updated fields', () => {
const visualComponentSchema: VisualComponentSchema = {
title: 'My Node',
schema: {
type: 'object',
properties: {
name: {
type: 'string',
},
},
} as unknown as KaotoSchemaDefinition['schema'],
definition: {
name: 'my node',
failoverLoadBalancer: {
id: 'test',
},
},
};

mockNode = {
id: '1',
type: 'node',
data: {
vizNode: {
getComponentSchema: () => visualComponentSchema,
updateModel: (_value: unknown) => {},
} as IVisualizationNode,
},
};
render(<LoadBalancerEditor selectedNode={mockNode} formMode={FormTabsModes.USER_MODIFIED} />);
const buttons = screen.queryAllByRole('button', { name: 'Typeahead menu toggle' });
expect(buttons).toHaveLength(1);

const inputElement = screen.getAllByRole('combobox')[0];
expect(inputElement).toHaveValue('Failover Load Balancer');

const inputIdModifiedTabElement = screen
.queryAllByRole('textbox')
.filter((textbox) => textbox.getAttribute('label') === 'Id');
expect(inputIdModifiedTabElement).toHaveLength(1);
});

it('should render', async () => {
render(<LoadBalancerEditor selectedNode={mockNode} />);
render(<LoadBalancerEditor selectedNode={mockNode} formMode={FormTabsModes.ALL_FIELDS} />);
const buttons = screen.getAllByRole('button', { name: 'Typeahead menu toggle' });
await act(async () => {
fireEvent.click(buttons[0]);
Expand All @@ -61,7 +110,7 @@ describe('LoadBalancerEditor', () => {
});

it('should filter candidates with a text input', async () => {
render(<LoadBalancerEditor selectedNode={mockNode} />);
render(<LoadBalancerEditor selectedNode={mockNode} formMode={FormTabsModes.ALL_FIELDS} />);
const buttons = screen.getAllByRole('button', { name: 'Typeahead menu toggle' });
await act(async () => {
fireEvent.click(buttons[0]);
Expand All @@ -77,7 +126,7 @@ describe('LoadBalancerEditor', () => {
});

it('should clear filter and close the dropdown with close button', async () => {
render(<LoadBalancerEditor selectedNode={mockNode} />);
render(<LoadBalancerEditor selectedNode={mockNode} formMode={FormTabsModes.ALL_FIELDS} />);
const buttons = screen.getAllByRole('button', { name: 'Typeahead menu toggle' });
await act(async () => {
fireEvent.click(buttons[0]);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,12 @@ import { CanvasNode } from '../../Visualization/Canvas/canvas.models';
import { LoadBalancerService } from './loadbalancer.service';
import './LoadBalancerEditor.scss';
import { TypeaheadEditor } from '../customField/TypeaheadEditor';
import { getSerializedModel } from '../../../utils';
import { getSerializedModel, getUserUpdatedPropertiesSchema, isDefined } from '../../../utils';
import { FormTabsModes } from '../../Visualization/Canvas/canvasformtabs.modes';

interface LoadBalancerEditorProps {
selectedNode: CanvasNode;
formMode: FormTabsModes;
}

export const LoadBalancerEditor: FunctionComponent<LoadBalancerEditorProps> = (props) => {
Expand Down Expand Up @@ -46,6 +48,7 @@ export const LoadBalancerEditor: FunctionComponent<LoadBalancerEditorProps> = (p
loadBalancerCatalogMap,
visualComponentSchema?.definition,
);

const loadBalancerOption = loadBalancer && {
name: loadBalancer!.model.name,
title: loadBalancer!.model.title,
Expand All @@ -58,6 +61,14 @@ export const LoadBalancerEditor: FunctionComponent<LoadBalancerEditorProps> = (p
return LoadBalancerService.getLoadBalancerSchema(loadBalancer);
}, [loadBalancer]);

const processedSchema = useMemo(() => {
if (props.formMode === FormTabsModes.ALL_FIELDS) return loadBalancerSchema;
return {
...loadBalancerSchema,
properties: getUserUpdatedPropertiesSchema(loadBalancerSchema?.properties ?? {}, loadBalancerModel ?? {}),
};
}, [props.formMode, loadBalancer]);

const handleOnChange = useCallback(
(
selectedLoadBalancerOption: { name: string; title: string } | undefined,
Expand All @@ -78,6 +89,13 @@ export const LoadBalancerEditor: FunctionComponent<LoadBalancerEditorProps> = (p
[entitiesContext, loadBalancerCatalogMap, props.selectedNode.data?.vizNode],
);

const showEditor = useMemo(() => {
if (props.formMode === FormTabsModes.ALL_FIELDS) return true;
return props.formMode === FormTabsModes.USER_MODIFIED && isDefined(selectedLoadBalancerOption);
}, [props.formMode]);

if (!showEditor) return null;

return (
<div className="loadbalancer-metadata-editor">
<Card isCompact={true} isExpanded={isExpanded} className="loadbalancer-metadata-editor-card">
Expand All @@ -91,7 +109,7 @@ export const LoadBalancerEditor: FunctionComponent<LoadBalancerEditorProps> = (p
title="loadbalancer"
selected={selectedLoadBalancerOption}
selectedModel={loadBalancerModel}
selectedSchema={loadBalancerSchema}
selectedSchema={processedSchema}
selectionOnChange={handleOnChange}
/>
</CardBody>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { MetadataEditor } from '../../MetadataEditor';
import { CanvasNode } from '../../Visualization/Canvas/canvas.models';
import { SchemaService } from '../schema.service';
import { StepExpressionEditor } from './StepExpressionEditor';
import { FormTabsModes } from '../../Visualization/Canvas/canvasformtabs.modes';

describe('StepExpressionEditor', () => {
let mockNode: CanvasNode;
Expand Down Expand Up @@ -45,8 +46,14 @@ describe('StepExpressionEditor', () => {
};
});

it('should not render', () => {
render(<StepExpressionEditor selectedNode={mockNode} formMode={FormTabsModes.USER_MODIFIED} />);
const launcherButton = screen.queryAllByRole('button', { name: 'Configure Expression' });
expect(launcherButton).toHaveLength(0);
});

it('should render', async () => {
render(<StepExpressionEditor selectedNode={mockNode} />);
render(<StepExpressionEditor selectedNode={mockNode} formMode={FormTabsModes.ALL_FIELDS} />);
const launcherButton = screen.getAllByRole('button', { name: 'Configure Expression' });
await act(async () => {
fireEvent.click(launcherButton[0]);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@ import { EntitiesContext } from '../../../providers';
import { CanvasNode } from '../../Visualization/Canvas/canvas.models';
import { ExpressionService } from '..//expression/expression.service';
import { ExpressionModalLauncher } from '../expression/ExpressionModalLauncher';
import { getSerializedModel } from '../../../utils';
import { getSerializedModel, isDefined } from '../../../utils';
import { FormTabsModes } from '../../Visualization/Canvas/canvasformtabs.modes';

interface StepExpressionEditorProps {
selectedNode: CanvasNode;
formMode: FormTabsModes;
}

export const StepExpressionEditor: FunctionComponent<StepExpressionEditorProps> = (props) => {
Expand Down Expand Up @@ -65,6 +67,13 @@ export const StepExpressionEditor: FunctionComponent<StepExpressionEditorProps>
const title = props.selectedNode.label;
const description = title ? `Configure expression for "${title}" parameter` : 'Configure expression';

const showEditor = useMemo(() => {
if (props.formMode === FormTabsModes.ALL_FIELDS) return true;
return props.formMode === FormTabsModes.USER_MODIFIED && isDefined(preparedLanguage);
}, [props.formMode]);

if (!showEditor) return null;

return (
languageCatalogMap && (
<div className="expression-field pf-v5-c-form">
Expand Down
Loading

0 comments on commit 71e64c4

Please sign in to comment.