Skip to content

Commit

Permalink
Fix(CanvasForm): fetching Required field recursively resolving ''
Browse files Browse the repository at this point in the history
  • Loading branch information
shivamG640 committed Jan 10, 2025
1 parent a696c02 commit c64100f
Show file tree
Hide file tree
Showing 8 changed files with 72 additions and 28 deletions.
2 changes: 1 addition & 1 deletion packages/ui/src/components/Form/CustomAutoFields.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ export function CustomAutoFields({
const filteredfields = Object.entries(schemaObject ?? {}).filter(
(field) =>
(!omitFields!.includes(field[0]) && field[0].toLowerCase().includes(cleanQueryTerm)) ||
(field[1] as any).type === 'object',
(field[1] as { type: string }).type === 'object',
);

const propertiesArray = getFieldGroups(Object.fromEntries(filteredfields));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ export const CustomNestField = connectField(
const { filteredFieldText, isGroupExpanded } = useContext(FilteredFieldContext);
const cleanQueryTerm = filteredFieldText.replace(/\s/g, '').toLowerCase();
const filteredProperties = Object.entries(props.properties ?? {}).filter(
(field) => field[0].toLowerCase().includes(cleanQueryTerm) || (field[1] as any).type === 'object',
(field) => field[0].toLowerCase().includes(cleanQueryTerm) || (field[1] as { type: string }).type === 'object',
);
const actualProperties = Object.fromEntries(filteredProperties);
const propertiesArray = getFieldGroups(actualProperties);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ export const DataFormatEditor: FunctionComponent<DataFormatEditorProps> = (props

const processedSchema = useMemo(() => {
if (props.formMode === 'Required') {
return getRequiredPropertiesSchema(dataFormatSchema ?? {});
return getRequiredPropertiesSchema(dataFormatSchema, dataFormatSchema);
} else if (props.formMode === 'All') {
return dataFormatSchema;
} else if (props.formMode === 'Modified') {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ export const LoadBalancerEditor: FunctionComponent<LoadBalancerEditorProps> = (p

const processedSchema = useMemo(() => {
if (props.formMode === 'Required') {
return getRequiredPropertiesSchema(loadBalancerSchema ?? {});
return getRequiredPropertiesSchema(loadBalancerSchema, loadBalancerSchema);
} else if (props.formMode === 'All') {
return loadBalancerSchema;
} else if (props.formMode === 'Modified') {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ export const StepExpressionEditor: FunctionComponent<StepExpressionEditorProps>

const processedSchema = useMemo(() => {
if (props.formMode === 'Required') {
return getRequiredPropertiesSchema(languageSchema ?? {});
return getRequiredPropertiesSchema(languageSchema, languageSchema);
} else if (props.formMode === 'All') {
return languageSchema;
} else if (props.formMode === 'Modified') {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export const CanvasFormBody: FunctionComponent<CanvasFormTabsProps> = (props) =>
const model = visualComponentSchema?.definition;
let processedSchema = visualComponentSchema?.schema;
if (selectedTab === 'Required') {
processedSchema = getRequiredPropertiesSchema(visualComponentSchema?.schema ?? {});
processedSchema = getRequiredPropertiesSchema(visualComponentSchema?.schema, visualComponentSchema?.schema);
} else if (selectedTab === 'Modified') {
processedSchema = {
...visualComponentSchema?.schema,
Expand Down
35 changes: 32 additions & 3 deletions packages/ui/src/utils/get-required-properties-schema.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,20 @@ import { KaotoSchemaDefinition } from '../models/kaoto-schema';
describe('getRequiredPropertiesSchema()', () => {
const schema = {
type: 'object',
definitions: {
testRef: {
type: 'object',
title: 'testRef',
properties: {
spec: {
type: 'string',
title: 'Specification',
description: 'Path to the OpenApi specification file.',
},
},
required: ['spec'],
},
},
properties: {
id: {
title: 'Id',
Expand All @@ -21,6 +35,9 @@ describe('getRequiredPropertiesSchema()', () => {
title: 'Variable Receive',
type: 'string',
},
testRef: {
$ref: '#/definitions/testRef',
},
parameters: {
type: 'object',
title: 'Endpoint Properties',
Expand Down Expand Up @@ -154,6 +171,18 @@ describe('getRequiredPropertiesSchema()', () => {
title: 'Uri',
type: 'string',
},
testRef: {
type: 'object',
title: 'testRef',
properties: {
spec: {
type: 'string',
title: 'Specification',
description: 'Path to the OpenApi specification file.',
},
},
required: ['spec'],
},
parameters: {
type: 'object',
title: 'Endpoint Properties',
Expand Down Expand Up @@ -200,13 +229,13 @@ describe('getRequiredPropertiesSchema()', () => {
required: ['id', 'uri', 'labels'],
};

it('should return only the properties which are user Modified', () => {
const procesedSchema = getRequiredPropertiesSchema(schema);
it('should return only the properties which are Required', () => {
const procesedSchema = getRequiredPropertiesSchema(schema, schema);
expect(procesedSchema).toMatchObject(expectedSchema);
});

it('should return {}', () => {
const procesedSchema = getRequiredPropertiesSchema({});
const procesedSchema = getRequiredPropertiesSchema({}, schema);
expect(procesedSchema).toMatchObject({});
});
});
53 changes: 34 additions & 19 deletions packages/ui/src/utils/get-required-properties-schema.ts
Original file line number Diff line number Diff line change
@@ -1,30 +1,45 @@
import { KaotoSchemaDefinition } from '../models';
import { isDefined } from './is-defined';
import { resolveRefIfNeeded } from './resolve-ref-if-needed';

export function getRequiredPropertiesSchema(schema: KaotoSchemaDefinition['schema']): KaotoSchemaDefinition['schema'] {
if (!isDefined(schema)) return {};
/**
* Extracts a schema containing only the required properties.
* Recursively resolves `$ref` if necessary.
*/
export function getRequiredPropertiesSchema(
schema?: KaotoSchemaDefinition['schema'],
resolveFromSchema?: KaotoSchemaDefinition['schema'],
): KaotoSchemaDefinition['schema'] {
if (!isDefined(schema) || !isDefined(resolveFromSchema)) return {};

const schemaProperties = schema.properties;
const requiredProperties = schema.required as string[];

if (isDefined(requiredProperties) && isDefined(schemaProperties)) {
const requiredFormSchema = Object.entries(schemaProperties).reduce(
(acc, [property, definition]) => {
if (definition['type'] === 'object' && 'properties' in definition) {
const subSchema = getRequiredPropertiesSchema(definition);
if (Object.keys(subSchema.properties as object).length > 0) {
acc[property] = subSchema;
}
} else {
if (requiredProperties.indexOf(property) > -1) acc[property] = definition;
if (!isDefined(schemaProperties)) {
return { ...schema, properties: {} };
}

const requiredFormSchema = Object.entries(schemaProperties).reduce(
(acc, [property, definition]) => {
if ('$ref' in definition) {
const objectDefinition = resolveRefIfNeeded(definition, resolveFromSchema);
const subSchema = getRequiredPropertiesSchema(objectDefinition, resolveFromSchema);
if (Object.keys(subSchema.properties as object).length > 0) {
acc[property] = subSchema;
}
} else if (definition['type'] === 'object' && 'properties' in definition) {
const subSchema = getRequiredPropertiesSchema(definition, resolveFromSchema);
if (Object.keys(subSchema.properties as object).length > 0) {
acc[property] = subSchema;
}
} else {
if (isDefined(requiredProperties) && requiredProperties.indexOf(property) > -1) acc[property] = definition;
}

return acc;
},
{} as KaotoSchemaDefinition['schema'],
);
return { ...schema, properties: requiredFormSchema };
}
return acc;
},
{} as KaotoSchemaDefinition['schema'],
);

return { ...schema, properties: {} };
return { ...schema, properties: requiredFormSchema };
}

0 comments on commit c64100f

Please sign in to comment.