Skip to content

Commit

Permalink
feat(dep-wrapper-update): update depdency wrapper logic and testing (#…
Browse files Browse the repository at this point in the history
…691)

* working through logic for array fields

* add logic to correct setValue

* test file layout

* Update depedencyWrapper.test.tsx

* Update depedencyWrapper.test.tsx

* Update dependencyWrapper.tsx

* Update SlotField.tsx
  • Loading branch information
jdinh8124 authored Jul 30, 2024
1 parent adf94b7 commit f09d054
Show file tree
Hide file tree
Showing 4 changed files with 162 additions and 8 deletions.
3 changes: 2 additions & 1 deletion lib/packages/shared-types/forms.ts
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,8 @@ type Effects =
}
| {
type: "setValue";
newValue: unknown;
newValue: string | string[];
fieldName: string;
};

export interface DependencyRule {
Expand Down
2 changes: 0 additions & 2 deletions react-app/src/components/RHF/SlotField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,6 @@ export const SlotField = ({
: a.label.localeCompare(b.label),
);

console.log("props.customSort", props?.customSort);

return (
<Select
{...props}
Expand Down
28 changes: 23 additions & 5 deletions react-app/src/components/RHF/dependencyWrapper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,11 @@ const checkTriggeringValue = (
return !!dependency?.conditions?.every((d, i) => {
switch (d.type) {
case "expectedValue":
return dependentValue[i] === d?.expectedValue;
if (Array.isArray(dependentValue[i])) {
return (dependentValue[i] as unknown[]).includes(d.expectedValue);
} else {
return dependentValue[i] === d?.expectedValue;
}
case "valueExists":
return (
(Array.isArray(dependentValue[i]) &&
Expand Down Expand Up @@ -48,22 +52,36 @@ const DependencyWrapperHandler = ({
parentValue,
changeMethod,
}: PropsWithChildren<DependencyWrapperProps>) => {
const { watch, setValue } = useFormContext();
const { watch, setValue, getValues } = useFormContext();
const [wasSetLast, setWasSetLast] = useState(false);
const dependentValues = watch(
dependency?.conditions?.map((c) => c.name) ?? [],
);
const isTriggered =
dependency && checkTriggeringValue(dependentValues, dependency);

useEffect(() => {
if (
!wasSetLast &&
dependency?.effect.type === "setValue" &&
isTriggered &&
!!name
!!dependency?.effect.fieldName
) {
setValue(name, dependency.effect.newValue);
const value = getValues(dependency.effect.fieldName);
if (Array.isArray(value)) {
if (Array.isArray(dependency.effect.newValue)) {
setValue(dependency.effect.fieldName, [
...value,
...dependency.effect.newValue,
]);
} else {
setValue(dependency.effect.fieldName, [
...value,
dependency.effect.newValue,
]);
}
} else {
setValue(dependency.effect.fieldName, dependency.effect.newValue);
}
setWasSetLast(true);
} else if (!isTriggered && wasSetLast) {
setWasSetLast(false);
Expand Down
137 changes: 137 additions & 0 deletions react-app/src/components/RHF/tests/depedencyWrapper.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
import { describe, test, expect } from "vitest";
import { render } from "@testing-library/react";
import { useForm, FormProvider } from "react-hook-form";
import { DependencyWrapper } from "../dependencyWrapper";
import { PropsWithChildren } from "react";
import { DependencyRule } from "shared-types";

const TestComp = ({
name,
dependency,
parentValue,
changeMethod,
children,
}: PropsWithChildren<{
name: string;
dependency: DependencyRule;
parentValue: string[];
changeMethod: (values: string[]) => void;
}>) => {
const methods = useForm({
defaultValues: {
[name]: parentValue,
field1: "test",
field2: "",
},
});

return (
<FormProvider {...methods}>
<DependencyWrapper
name={name}
dependency={dependency}
parentValue={parentValue}
changeMethod={changeMethod}
>
{children}
</DependencyWrapper>
</FormProvider>
);
};

describe("DependencyWrapper Tests", () => {
test("test show effect", () => {
const dependency: DependencyRule = {
conditions: [
{ type: "expectedValue", expectedValue: "test", name: "field1" },
],
effect: { type: "show" },
};
const { getByText } = render(
<TestComp
name="testField"
dependency={dependency}
parentValue={["testField"]}
changeMethod={(value) => {
console.log(value);
}}
>
<div>Child Component</div>
</TestComp>,
);

expect(getByText("Child Component")).toBeTruthy();
});

test("test hide effect", () => {
const dependency: DependencyRule = {
conditions: [
{ type: "expectedValue", expectedValue: "test", name: "field1" },
],
effect: { type: "hide" },
};
const { queryByText } = render(
<TestComp
name="testField"
dependency={dependency}
parentValue={["testField"]}
changeMethod={(value) => {
console.log(value);
}}
>
<div>Child Component</div>
</TestComp>,
);

expect(queryByText("Child Component")).toBeNull();
});

test("test set value effect", () => {
const dependency: DependencyRule = {
conditions: [
{ type: "expectedValue", expectedValue: "test", name: "field1" },
],
effect: { type: "setValue", fieldName: "field2", newValue: "newValue" },
};

let methods: any;

const TestCompWithMethods = (
props: PropsWithChildren<{
name: string;
dependency: DependencyRule;
parentValue: string[];
changeMethod: (values: string[]) => void;
}>,
) => {
methods = useForm({
defaultValues: {
[props.name]: props.parentValue,
field1: "test",
field2: "",
},
});

return (
<FormProvider {...methods}>
<DependencyWrapper {...props}>{props.children}</DependencyWrapper>
</FormProvider>
);
};

render(
<TestCompWithMethods
name="testField"
dependency={dependency}
parentValue={["testField"]}
changeMethod={(value) => {
console.log(value);
}}
>
<div>Child Component</div>
</TestCompWithMethods>,
);

expect(methods.getValues("field2")).toBe("newValue");
});
});

0 comments on commit f09d054

Please sign in to comment.