Skip to content

Commit 915b0c7

Browse files
committed
Render SDK errors in an alert
1 parent b5374a3 commit 915b0c7

File tree

3 files changed

+55
-44
lines changed

3 files changed

+55
-44
lines changed

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

Lines changed: 12 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -27,37 +27,20 @@ export function Errors<T extends ConfigurableProps, U extends ConfigurableProp>(
2727
// TODO depending on type does different shit... we might need async loader around the label, etc.?
2828
// maybe that should just be handled by FormFieldContext instead of container?
2929

30-
const formattedErrors: ConfigurablePropAlert[] = []
31-
// for (const key in fieldErrors) {
32-
const key = "xxx"
33-
if (key === "sdkErrors") {
34-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
35-
// @ts-expect-error
36-
formattedErrors.push(...errors[key].map((e) => {
37-
const o = JSON.parse(e)
38-
return {
39-
type: "alert",
40-
alertType: "error",
41-
content: `#${o.name}\n${o.message}`,
42-
}
43-
}))
44-
} else {
45-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
46-
// @ts-expect-error
47-
formattedErrors.push(...errors[prop.name].map((e) => {
48-
return {
49-
type: "alert",
50-
alertType: "error",
51-
content: e,
52-
}
53-
}))
30+
const formattedErrors: ConfigurablePropAlert[] = errors[prop.name].map((e) => {
31+
return {
32+
type: "alert",
33+
alertType: "error",
34+
content: e,
35+
}
36+
})
37+
38+
const baseStyles = {
39+
display: "grid",
40+
gridTemplateColumns: "max-content",
5441
}
55-
// }
5642

5743
return (
58-
// <ul {...getProps("errors", baseStyles, props)}>
59-
// {errors.map((msg) => <li key={msg} {...getProps("error", baseStyles, props)}>{msg}</li>)}
60-
// </ul>
61-
<>{formattedErrors.map((fe, idx: number) => <Alert prop={fe} key={idx}/>)}</>
44+
<div className="pd-errors" style={baseStyles}>{formattedErrors.map((fe, idx: number) => <Alert prop={fe} key={idx}/>)}</div>
6245
);
6346
}

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

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
import { Suspense } from "react";
1+
import {
2+
Suspense, useEffect, useState,
3+
} from "react";
24
import type {
35
CSSProperties, FormEventHandler,
46
} from "react";
@@ -23,12 +25,37 @@ export function InternalComponentForm() {
2325
optionalPropSetEnabled,
2426
props: formContextProps,
2527
setSubmitting,
28+
sdkErrors: __sdkErrors,
29+
submitting,
2630
} = formContext;
2731

2832
const {
2933
hideOptionalProps, onSubmit,
3034
} = formContextProps;
3135

36+
const [
37+
sdkErrors,
38+
setSdkErrors,
39+
] = useState<ConfigurablePropAlert[]>([])
40+
41+
useEffect(() => {
42+
if (submitting) setSdkErrors([])
43+
else {
44+
if (__sdkErrors && __sdkErrors.length) {
45+
setSdkErrors(__sdkErrors.map((e) => {
46+
return {
47+
type: "alert",
48+
alertType: "error",
49+
content: `# ${e.name}\n${e.message}`,
50+
}
51+
}))
52+
}
53+
}
54+
}, [
55+
__sdkErrors,
56+
submitting,
57+
]);
58+
3259
const {
3360
getComponents, getProps, theme,
3461
} = useCustomize();
@@ -96,6 +123,7 @@ export function InternalComponentForm() {
96123
}
97124

98125
// TODO improve the error boundary thing (use default Alert component maybe)
126+
99127
return (
100128
<ErrorBoundary fallback={(err) => <p style={{
101129
color: "red",
@@ -130,6 +158,7 @@ export function InternalComponentForm() {
130158
</div>
131159
</div>
132160
: null}
161+
{ sdkErrors?.map((e, idx) => <Alert prop={e} key={idx}/>)}
133162
{onSubmit && <ControlSubmit form={formContext} />}
134163
</form>
135164
</Suspense>

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

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ export type FormContext<T extends ConfigurableProps> = {
2424
dynamicProps?: DynamicProps<T>; // lots of calls require dynamicProps?.id, so need to expose
2525
dynamicPropsQueryIsFetching?: boolean;
2626
errors: Record<string, string[]>;
27+
sdkErrors: Record<string, string>[];
2728
fields: Record<string, FormFieldContext<ConfigurableProp>>;
2829
id: string;
2930
isValid: boolean;
@@ -73,7 +74,7 @@ export const FormContextProvider = <T extends ConfigurableProps>({
7374
const id = useId();
7475

7576
const {
76-
component, configuredProps: __configuredProps, propNames, userId, sdkErrors,
77+
component, configuredProps: __configuredProps, propNames, userId, sdkErrors: __sdkErrors,
7778
} = formProps;
7879
const componentId = component.key;
7980

@@ -95,9 +96,9 @@ export const FormContextProvider = <T extends ConfigurableProps>({
9596
] = useState<Record<string, string[]>>({});
9697

9798
const [
98-
configurationErrors,
99-
setConfigurationErrors,
100-
] = useState<string[]>([]);
99+
sdkErrors,
100+
setSdkErrors,
101+
] = useState<Record<string, string>[]>([])
101102

102103
const [
103104
enabledOptionalProps,
@@ -270,9 +271,9 @@ export const FormContextProvider = <T extends ConfigurableProps>({
270271
]);
271272

272273
useEffect(() => {
273-
handleSdkErrors(sdkErrors)
274+
handleSdkErrors(__sdkErrors)
274275
}, [
275-
sdkErrors,
276+
__sdkErrors,
276277
]);
277278

278279
useEffect(() => {
@@ -411,18 +412,15 @@ export const FormContextProvider = <T extends ConfigurableProps>({
411412
const os = o
412413
if (Array.isArray(os) && os.length > 0) {
413414
const newErrors = os.map((it) => {
414-
const name = it.err?.name
415-
const message = it.err?.message
416-
if (name && message) return JSON.stringify({
415+
const name: string = it.err?.name
416+
const message: string = it.err?.message
417+
if (name && message) return {
417418
name,
418419
message,
419-
})
420+
} as Record<string, string>
420421
return undefined
421422
}).filter((e) => e !== undefined)
422-
if (newErrors) setErrors({
423-
...errors,
424-
sdkErrors: newErrors,
425-
})
423+
setSdkErrors(newErrors)
426424
} else if (typeof o === "object") {
427425
// TODO: handle rails api errors here
428426
}
@@ -449,6 +447,7 @@ export const FormContextProvider = <T extends ConfigurableProps>({
449447
setConfiguredProp,
450448
setSubmitting,
451449
submitting,
450+
sdkErrors,
452451
};
453452
return <FormContext.Provider value={value}>{children}</FormContext.Provider>;
454453
};

0 commit comments

Comments
 (0)