'validation' turned to 'getError' for consistency

Massimo Melina committed May 30, 2022 at 12:49 UTC 70036fdfada30d0d21dfa6c900a764f3accdd54a
3 files changed +12 -15
admin/src/AccountsPage.ts
+1 -1
@@ -169,7 +169,7 @@ function AccountForm({ account, done, groups, close }: FormProps) {
169 label: add ? "Password" : "Change password"
170 },
171 !group && { k: 'password2', md: 6, xl: 4, type: 'password', autoComplete: 'new-password', label: 'Repeat password',
172 - validate: (x, { values }) => x === values.password || "Enter same password" },
172 + getError: (x, { values }) => x !== values.password && "Enter same password" },
173 { k: 'ignore_limits', comp: BoolField, xl: 6,
174 helperText: values.ignore_limits ? "Speed limits don't apply to this account" : "Speed limits apply to this account" },
175 { k: 'admin', comp: BoolField, xl: 6, fromField: (v:boolean) => v||null, label: "Permission to access Admin interface",
admin/src/ConfigPage.ts
+2 -2
@@ -87,7 +87,7 @@ export default function ConfigPage() {
87 values.https_port >= 0 && { k: 'private_key', comp: FileField, label: "HTTPS private key file" },
88 { k: 'open_browser_at_start', comp: BoolField },
89 { k: 'localhost_admin', comp: BoolField, label: "Admin access for localhost connections",
90 - validate: x => x || !admins || admins.length>0 || "First create at least one admin account",
90 + getError: x => !x && admins?.length===0 && "First create at least one admin account",
91 helperText: "To access Admin without entering credentials"
92 },
93 { k: 'log', label: logLabels.log, lg: 3, helperText: "Requests are logged here" },
@@ -215,7 +215,7 @@ export async function makeCertAndSave() {
215 try {
216 const saved = await apiCall('save_pem', await makeCert(res))
217 await apiCall('set_config', { values: saved })
218 - if (loaded) // when undefined we are outside of this page
218 + if (loaded) // when undefined we are not in this page
219 Object.assign(loaded, saved)
220 setTimeout(exposedReloadStatus!, 1000) // give some time for backend to apply
221 Object.assign(state.config, saved)
admin/src/Form.ts
+9 -12
@@ -29,12 +29,12 @@ import { LoadingButton } from '@mui/lab'
29 import _ from 'lodash'
30 import { SxProps } from '@mui/system'
31
32 -type Validate = (v: any, extra?: any) => string | boolean
32 +type ValidationError = string | boolean // false = no error
33 export interface FieldDescriptor<T=any> {
34 k: string
35 comp?: any
36 label?: ReactNode
37 - validate?: Validate
37 + getError?: (v: any, extra?: any) => Promisable<ValidationError>
38 toField?: (v: T) => any
39 fromField?: (v: any) => T
40 [extraProp: string]: any
@@ -68,7 +68,7 @@ export function Form<Values extends Dict>({ fields, values, set, defaults, save,
68 }
69 }, [])
70
71 - const [errors, setErrors] = useState<Dict<string | false>>({})
71 + const [errors, setErrors] = useState<Dict<ValidationError>>({})
72 const saveBtn = typeof save === 'function' ? { onClick: save } : save // normalize
73 const [phase, setPhase] = useState(Phase.Idle)
74 const submitAfterValidation = useRef(false)
@@ -98,9 +98,9 @@ export function Form<Values extends Dict>({ fields, values, set, defaults, save,
98 return null
99 if (isValidElement(row))
100 return h(Grid, { key: idx, item: true, xs: 12 }, row)
101 - const { k, fromField=_.identity, toField=_.identity, validate, ...field } = row
101 + const { k, fromField=_.identity, toField=_.identity, getError, ...field } = row
102 let error = errors[k]
103 - if (error === '')
103 + if (error === true)
104 error = "Not valid"
105 if (k) {
106 const originalValue = values?.[k]
@@ -184,12 +184,9 @@ export function Form<Values extends Dict>({ fields, values, set, defaults, save,
184 if (!f || isValidElement(f) || !f.k) continue
185 const { k } = f
186 const v = values?.[k]
187 - let err = await apis[k]?.getError()
188 - if (!err) {
189 - const res = await f.validate?.(v, { values, fields })
190 - err = res !== undefined && res !== true && (res || '')
191 - }
192 - errs[k] = err
187 + const err = await apis[k]?.getError()
188 + || await f.getError?.(v, { values, fields })
189 + errs[k] = err || false
190 if (k === validateUpTo.current) break
191 if (!mounted.current) return // abort
192 }
@@ -217,7 +214,7 @@ export function labelFromKey(k: string) {
214 }
215
216 type Promisable<T> = T | Promise<T>
220 -interface FieldApi { getError: () => Promisable<string | false>, [rest: string]: any }
217 +interface FieldApi { getError: () => Promisable<ValidationError>, [rest: string]: any }
218 export interface FieldProps<T> {
219 label?: string | ReactElement
220 value?: T