Skip to content

Commit

Permalink
fix(ui): temp fix added for rjsf schema anyof type. (#722)
Browse files Browse the repository at this point in the history
  • Loading branch information
billcookie authored Dec 20, 2024
1 parent 3d906d1 commit c095f40
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ const ArrayFieldItemTemplate = <
<div>
<div className="mb-2 flex items-center gap-1">
<div>{children}</div>
{/* TODO: depending on the type of the children, stylings for icons are broken. */}
<div className="pt-4">
{hasToolbar && (
<div className="flex flex-row gap-1">
Expand Down
58 changes: 58 additions & 0 deletions ui/src/components/SchemaForm/patchSchemaTypes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { RJSFSchema } from "@rjsf/utils";
import { JSONSchema7, JSONSchema7Definition } from "json-schema";

// This is a workaround for the `anyOf` type for RJSF/JSON Schema. Currently if "null" only is passed as a type in `anyof` it won't work as expected.
// We should regualry check this issue and update RJSF once a fix is published. (https://github.com/rjsf-team/react-jsonschema-form/issues/4380)
const isJSONSchema = (schema: JSONSchema7Definition): schema is JSONSchema7 =>
typeof schema !== "boolean";

export const patchAnyOfType = (schema: JSONSchema7Definition): RJSFSchema => {
if (!isJSONSchema(schema)) {
return { type: "boolean", default: schema };
}

const newSchema: JSONSchema7 = { ...schema };

if (newSchema.properties) {
newSchema.properties = Object.entries(newSchema.properties).reduce(
(acc, [key, value]) => ({
...acc,
[key]: patchAnyOfType(value),
}),
{},
);
}

if (newSchema.definitions) {
newSchema.definitions = Object.entries(newSchema.definitions).reduce(
(acc, [key, value]) => ({
...acc,
[key]: patchAnyOfType(value),
}),
{},
);
}

if (newSchema.anyOf) {
const refSchema = newSchema.anyOf.find((s) => isJSONSchema(s) && s.$ref);
const nullSchema = newSchema.anyOf.find(
(s) => isJSONSchema(s) && s.type === "null",
);

if (refSchema && nullSchema && isJSONSchema(refSchema)) {
delete newSchema.anyOf;
newSchema.type = ["string", "null"];
newSchema.$ref = refSchema.$ref;
}
}

if (newSchema.items) {
if (Array.isArray(newSchema.items)) {
newSchema.items = newSchema.items.map((item) => patchAnyOfType(item));
} else {
newSchema.items = patchAnyOfType(newSchema.items);
}
}

return newSchema as RJSFSchema;
};
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import { ArrowLeft, ArrowRight } from "@phosphor-icons/react";
import { memo } from "react";
import { RJSFSchema } from "@rjsf/utils";
import { JSONSchema7Definition } from "json-schema";
import { memo, useMemo } from "react";

import { IconButton, Tabs, TabsContent, SchemaForm } from "@flow/components";
import { patchAnyOfType } from "@flow/components/SchemaForm/patchSchemaTypes";
import { useAction } from "@flow/lib/fetch";
import { useT } from "@flow/lib/i18n";
import type { NodeData } from "@flow/types";
Expand All @@ -28,7 +31,17 @@ const ParamEditor: React.FC<Props> = ({
const { useGetActionById } = useAction();
const { action } = useGetActionById(nodeMeta.officialName);

// This is a patch for the `anyOf` type in JSON Schema.
const patchedSchema = useMemo<RJSFSchema | undefined>(
() =>
action?.parameter
? patchAnyOfType(action.parameter as JSONSchema7Definition)
: undefined,
[action?.parameter],
);

const handleSubmit = (data: any) => onSubmit(nodeId, data);

return (
<div>
<div className="mb-3 flex justify-between gap-4">
Expand Down Expand Up @@ -58,7 +71,7 @@ const ParamEditor: React.FC<Props> = ({
{!action?.parameter && <p>{t("No Parameters Available")}</p>}
{action && (
<SchemaForm
schema={action.parameter}
schema={patchedSchema}
defaultFormData={nodeMeta.params}
onSubmit={handleSubmit}
/>
Expand Down

0 comments on commit c095f40

Please sign in to comment.