Skip to content

Commit 338e3aa

Browse files
committed
Register fields with form to enable complete error checking
1 parent 44373f7 commit 338e3aa

File tree

3 files changed

+36
-6
lines changed

3 files changed

+36
-6
lines changed

packages/connect-react/examples/nextjs/package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/connect-react/src/components/InternalField.tsx

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { FormFieldContext } from "../hooks/form-field-context";
33
import { useFormContext } from "../hooks/form-context";
44
import { Field } from "./Field";
55
import { useApp } from "../hooks/use-app";
6+
import { useEffect } from "react";
67

78
type FieldInternalProps<T extends ConfigurableProp> = {
89
prop: T;
@@ -14,7 +15,7 @@ export function InternalField<T extends ConfigurableProp>({
1415
}: FieldInternalProps<T>) {
1516
const formCtx = useFormContext();
1617
const {
17-
id: formId, configuredProps, setConfiguredProp,
18+
id: formId, configuredProps, registerField, setConfiguredProp,
1819
} = formCtx;
1920

2021
const appSlug = prop.type === "app" && "app" in prop
@@ -44,7 +45,11 @@ export function InternalField<T extends ConfigurableProp>({
4445
app, // XXX fix ts
4546
},
4647
};
47-
48+
useEffect(() => registerField(fieldCtx), [
49+
app,
50+
configuredProps,
51+
prop,
52+
])
4853
return (
4954
<FormFieldContext.Provider value={fieldCtx}>
5055
<Field field={fieldCtx} form={formCtx} />

packages/connect-react/src/hooks/form-context.tsx

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import type {
88
} from "@pipedream/sdk";
99
import { useFrontendClient } from "./frontend-client-context";
1010
import type { ComponentFormProps } from "../components/ComponentForm";
11+
import type { FormFieldContext } from "./form-field-context";
1112

1213
export type DynamicProps<T extends ConfigurableProps> = { id: string; configurable_props: T; }; // TODO
1314

@@ -17,12 +18,14 @@ export type FormContext<T extends ConfigurableProps> = {
1718
configuredProps: ConfiguredProps<T>;
1819
dynamicProps?: DynamicProps<T>; // lots of calls require dynamicProps?.id, so need to expose
1920
dynamicPropsQueryIsFetching?: boolean;
21+
fields: Record<string, FormFieldContext<ConfigurableProp>>;
2022
id: string;
2123
isValid: boolean;
2224
optionalPropIsEnabled: (prop: ConfigurableProp) => boolean;
2325
optionalPropSetEnabled: (prop: ConfigurableProp, enabled: boolean) => void;
2426
props: ComponentFormProps<T>;
2527
queryDisabledIdx?: number;
28+
registerField: <T extends ConfigurableProp>(field: FormFieldContext<T>) => void;
2629
setConfiguredProp: (idx: number, value: unknown) => void; // XXX type safety for value (T will rarely be static right?)
2730
setSubmitting: (submitting: boolean) => void;
2831
submitting: boolean;
@@ -64,6 +67,10 @@ export const FormContextProvider = <T extends ConfigurableProps>({
6467
queryDisabledIdx,
6568
setQueryDisabledIdx,
6669
] = useState<number | undefined>(0);
70+
const [
71+
fields,
72+
setFields,
73+
] = useState<Record<string, FormFieldContext<ConfigurableProp>>>({});
6774
const [
6875
submitting,
6976
setSubmitting,
@@ -173,7 +180,14 @@ export const FormContextProvider = <T extends ConfigurableProps>({
173180
errs.push("not a string");
174181
}
175182
} else if (prop.type === "app") {
176-
// TODO need to know about auth type
183+
const field = fields[prop.name]
184+
if (!field.extra.app) {
185+
errs.push("app field not registered")
186+
} else if (!value) {
187+
errs.push("no app configured")
188+
} else if (typeof value === "object" && "authProvisionId" in value && !value.authProvisionId) {
189+
errs.push("no auth provision configured")
190+
}
177191
}
178192
return errs;
179193
};
@@ -241,7 +255,10 @@ export const FormContextProvider = <T extends ConfigurableProps>({
241255
]);
242256

243257
// clear all props on user change
244-
const [prevUserId, setPrevUserId] = useState(userId)
258+
const [
259+
prevUserId,
260+
setPrevUserId,
261+
] = useState(userId)
245262
useEffect(() => {
246263
if (prevUserId !== userId) {
247264
updateConfiguredProps({});
@@ -299,6 +316,11 @@ export const FormContextProvider = <T extends ConfigurableProps>({
299316
setEnabledOptionalProps(newEnabledOptionalProps);
300317
};
301318

319+
const registerField = <T extends ConfigurableProp>(field: FormFieldContext<T>) => {
320+
fields[field.prop.name] = field
321+
setFields(fields);
322+
};
323+
302324
// console.log("***", configurableProps, configuredProps)
303325
const value: FormContext<T> = {
304326
id,
@@ -310,9 +332,12 @@ export const FormContextProvider = <T extends ConfigurableProps>({
310332
configuredProps,
311333
dynamicProps,
312334
dynamicPropsQueryIsFetching,
335+
errors,
336+
fields,
313337
optionalPropIsEnabled,
314338
optionalPropSetEnabled,
315339
queryDisabledIdx,
340+
registerField,
316341
setConfiguredProp,
317342
setSubmitting,
318343
submitting,

0 commit comments

Comments
 (0)