Skip to content

Commit

Permalink
Merge pull request #73 from bleu-fi/joao/click-700-atualizar-pergunta…
Browse files Browse the repository at this point in the history
…s-de-diagnostico-para-ultima-versao

refactor withConditional to accept multiple conditions types
  • Loading branch information
devjoaov authored May 6, 2024
2 parents b06db60 + 8ff4941 commit 6cb7c1c
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 25 deletions.
46 changes: 23 additions & 23 deletions src/components/FormBuilder/fields.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,14 @@ import { TextAreaFieldProps } from "./fields/TextAreaField";
import { FieldArrayFieldProps } from "./fields/FieldArray";
import { FieldComponentType } from "./buildForm";

export interface Conditions {
[key: string]: any;
allOf?: Conditions[];
anyOf?: Conditions[];
}
export interface BaseField {
component?: React.ComponentType<CommonFieldProps<BaseField>>;
conditions?: Array<{
name: string;
value: string | Array<string>;
}>;
conditions?: Conditions;
defaultValue?: string;
description?: string;
disabled?: boolean | ((data: FieldValues) => boolean);
Expand All @@ -44,28 +46,26 @@ export function withConditional<T extends BaseField>(
return (props: CommonFieldProps<T>) => {
const { form, field } = props;

const conditions = Array.isArray(field.conditions)
? field.conditions
: null;

if (!conditions) return <Component {...props} />;
const evaluateConditions = (conditions: Conditions): boolean => {
if (conditions.allOf) {
return conditions.allOf.every(evaluateConditions);
}
if (conditions.anyOf) {
return conditions.anyOf.some(evaluateConditions);
}

const watchedFields = conditions.map((condition) =>
condition
? form.watch(condition.name.replace("RESOURCE_ID", String(field.index)))
: null
);
if (Object.keys(conditions).length === 0) return true;

// determine if all conditions are satisfied
const shouldRender = conditions.every((condition, index) => {
if (!condition) return true; // No condition means always render
const key = Object.keys(conditions)[0];
const watchField = form.watch(
key.replace("RESOURCE_ID", String(field.index))
);
const values = conditions[key];
return values.includes(watchField);
};

const watchField = watchedFields[index];
if (condition.value instanceof Array) {
return condition.value.includes(watchField);
}
return watchField === condition.value;
});
const conditionRoot = field.conditions ? field.conditions : {};
const shouldRender = evaluateConditions(conditionRoot);

if (!shouldRender) return null;

Expand Down
8 changes: 6 additions & 2 deletions tests/components/FormBuilder/withConditional.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ describe("withConditional", () => {
name: "test",
type: "input",
value: "",
conditions: [{ name: "test", value: "value" }],
conditions: {
allOf: [{ test: ["value"] }],
},
};
const form = renderHook(() =>
useForm({
Expand All @@ -31,7 +33,9 @@ describe("withConditional", () => {
name: "test",
type: "input",
value: "",
conditions: [{ name: "test", value: "value" }],
conditions: {
allOf: [{ test: ["value"] }],
},
};
const form = renderHook(() => useForm()).result.current;
render(<ConditionalComponent field={field} form={form} />);
Expand Down

0 comments on commit 6cb7c1c

Please sign in to comment.