Skip to content

Commit 7f3a3e6

Browse files
committed
Fix for submitting custom error form
1 parent c731751 commit 7f3a3e6

File tree

1 file changed

+44
-27
lines changed
  • apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.errors.$fingerprint

1 file changed

+44
-27
lines changed

apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.errors.$fingerprint/route.tsx

Lines changed: 44 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ import {
104104
DialogTrigger,
105105
} from "~/components/primitives/Dialog";
106106
import { ErrorGroupActions } from "~/v3/services/errorGroupActions.server";
107+
import { FormError } from "~/components/primitives/FormError";
107108

108109
export const meta: MetaFunction<typeof loader> = ({ data }) => {
109110
return [
@@ -113,6 +114,11 @@ export const meta: MetaFunction<typeof loader> = ({ data }) => {
113114
];
114115
};
115116

117+
const emptyStringToUndefined = z.preprocess(
118+
(v) => (v === "" ? undefined : v),
119+
z.coerce.number().positive().optional()
120+
);
121+
116122
const actionSchema = z.discriminatedUnion("action", [
117123
z.object({
118124
action: z.literal("resolve"),
@@ -122,10 +128,10 @@ const actionSchema = z.discriminatedUnion("action", [
122128
z.object({
123129
action: z.literal("ignore"),
124130
taskIdentifier: z.string().min(1),
125-
duration: z.coerce.number().positive().optional(),
126-
occurrenceRate: z.coerce.number().positive().optional(),
127-
totalOccurrences: z.coerce.number().positive().optional(),
128-
reason: z.string().optional(),
131+
duration: emptyStringToUndefined,
132+
occurrenceRate: emptyStringToUndefined,
133+
totalOccurrences: emptyStringToUndefined,
134+
reason: z.preprocess((v) => (v === "" ? undefined : v), z.string().optional()),
129135
}),
130136
z.object({
131137
action: z.literal("unresolve"),
@@ -684,20 +690,13 @@ function IgnoredDetails({
684690
<Paragraph variant="extra-small/dimmed">
685691
{state.ignoredByUserDisplayName && <>Configured by {state.ignoredByUserDisplayName}</>}
686692
{state.ignoredByUserDisplayName && state.ignoredAt && " "}
687-
{state.ignoredAt && (
688-
<RelativeDateTime
689-
date={state.ignoredAt}
690-
capitalize={false}
691-
/>
692-
)}
693+
{state.ignoredAt && <RelativeDateTime date={state.ignoredAt} capitalize={false} />}
693694
</Paragraph>
694695
)}
695696
</div>
696697

697698
{state.ignoredReason && (
698-
<div className="text-text-dimmed">
699-
Reason: <span className="text-text-bright">{state.ignoredReason}</span>
700-
</div>
699+
<Paragraph variant="extra-small/dimmed">Reason: {state.ignoredReason}</Paragraph>
701700
)}
702701

703702
{hasConditions && (
@@ -814,16 +813,24 @@ function ErrorStatusDropdown({
814813
</>
815814
)}
816815

817-
{state.status === "RESOLVED" && (
818-
<PopoverMenuItem
819-
icon={ArrowBackUpIcon}
820-
leadingIconClassName="text-error"
821-
title="Unresolved"
822-
onClick={() => act({ taskIdentifier, action: "unresolve" })}
823-
/>
816+
{state.status === "IGNORED" && (
817+
<>
818+
<PopoverMenuItem
819+
icon={CheckIcon}
820+
leadingIconClassName="text-success"
821+
title="Resolved"
822+
onClick={() => act({ taskIdentifier, action: "resolve" })}
823+
/>
824+
<PopoverMenuItem
825+
icon={ArrowBackUpIcon}
826+
leadingIconClassName="text-error"
827+
title="Unresolved"
828+
onClick={() => act({ taskIdentifier, action: "unresolve" })}
829+
/>
830+
</>
824831
)}
825832

826-
{state.status === "IGNORED" && (
833+
{state.status === "RESOLVED" && (
827834
<PopoverMenuItem
828835
icon={ArrowBackUpIcon}
829836
leadingIconClassName="text-error"
@@ -859,12 +866,23 @@ function CustomIgnoreForm({
859866
const submit = useSubmit();
860867
const navigation = useNavigation();
861868
const isSubmitting = navigation.state !== "idle";
869+
const [conditionError, setConditionError] = useState<string | null>(null);
862870

863871
return (
864872
<Form
865873
method="post"
866874
onSubmit={(e) => {
867875
e.preventDefault();
876+
const formData = new FormData(e.currentTarget);
877+
const rate = formData.get("occurrenceRate")?.toString().trim();
878+
const total = formData.get("totalOccurrences")?.toString().trim();
879+
880+
if (!rate && !total) {
881+
setConditionError("At least one unignore condition is required");
882+
return;
883+
}
884+
885+
setConditionError(null);
868886
submit(e.currentTarget, { method: "post" });
869887
setTimeout(onClose, 100);
870888
}}
@@ -883,6 +901,7 @@ function CustomIgnoreForm({
883901
type="number"
884902
min={1}
885903
placeholder="e.g. 10"
904+
onChange={() => conditionError && setConditionError(null)}
886905
/>
887906
</InputGroup>
888907

@@ -896,19 +915,17 @@ function CustomIgnoreForm({
896915
type="number"
897916
min={1}
898917
placeholder="e.g. 100"
918+
onChange={() => conditionError && setConditionError(null)}
899919
/>
900920
</InputGroup>
901921

922+
{conditionError && <FormError>{conditionError}</FormError>}
923+
902924
<InputGroup fullWidth>
903925
<Label htmlFor="reason" variant="small" required={false}>
904926
Reason
905927
</Label>
906-
<Input
907-
id="reason"
908-
name="reason"
909-
type="text"
910-
placeholder="e.g. Known flaky test"
911-
/>
928+
<Input id="reason" name="reason" type="text" placeholder="e.g. Known flaky test" />
912929
</InputGroup>
913930
</div>
914931

0 commit comments

Comments
 (0)