diff --git a/src/components/CriteriaForm/CriteriaForm.tsx b/src/components/CriteriaForm/CriteriaForm.tsx index 2e94b9802..89849d4ed 100644 --- a/src/components/CriteriaForm/CriteriaForm.tsx +++ b/src/components/CriteriaForm/CriteriaForm.tsx @@ -49,6 +49,10 @@ const StyledSubmitButton = styled(Button)` justify-content: center; `; +const StyledGoalSuggest = styled(GoalSuggest)` + flex: 1; +`; + interface WeightFieldProps { name: 'weight'; value?: string; @@ -107,7 +111,7 @@ const CriteriaTitleField = forwardRef /> {type === 'search' ? ( - !data.title.some((t) => t === val), { message: tr('Title must be unique'), }), - weight: schema.shape.weight - .transform((val) => Number(val)) - .refine((val) => !Number.isNaN(val), { message: tr('Weight must be integer') }) - .refine((val) => val >= minPossibleWeight && data.sum + val <= maxPossibleWeigth, { - message: tr - .raw('Weight must be in range', { - upTo: `${maxPossibleWeigth - data.sum}`, - }) - .join(''), - }), + // INFO: https://github.com/colinhacks/zod#abort-early + weight: schema.shape.weight.superRefine((val, ctx): val is string => { + if (!val || !val.length) { + return z.NEVER; + } + + const parsed = Number(val); + + if (Number.isNaN(parsed)) { + ctx.addIssue({ + code: z.ZodIssueCode.custom, + message: tr('Weight must be integer'), + }); + } + + if (parsed < minPossibleWeight || data.sum + parsed > maxPossibleWeigth) { + ctx.addIssue({ + code: z.ZodIssueCode.custom, + message: tr + .raw('Weight must be in range', { + upTo: `${maxPossibleWeigth - data.sum}`, + }) + .join(''), + }); + } + + return z.NEVER; + }), }), ); diff --git a/src/components/GoalCriteria/GoalCriteria.tsx b/src/components/GoalCriteria/GoalCriteria.tsx index 863386c54..75f8ea312 100644 --- a/src/components/GoalCriteria/GoalCriteria.tsx +++ b/src/components/GoalCriteria/GoalCriteria.tsx @@ -321,7 +321,7 @@ export const GoalCriteria: React.FC = ({ const dataForValidateCriteria = useMemo( () => - criteriaList.reduce( + criteriaList.reduce<{ sum: number; title: string[] }>( (acc, { weight, title }, criteriaIdx) => { if (mode === 'edit' && index === criteriaIdx) { return acc; @@ -332,7 +332,7 @@ export const GoalCriteria: React.FC = ({ }, { sum: 0, - title: [] as string[], + title: [], }, ), [criteriaList, mode, index], @@ -405,7 +405,7 @@ export const GoalCriteria: React.FC = ({ goalId, goalAsGriteria: item.goalIdAsCriteria != null ? { id: item.goalIdAsCriteria } : undefined, - weight: String(item.weight), + weight: item.weight ? String(item.weight) : '', }} onSubmit={onUpdateCriteria} onReset={() =>