Repository navigation
fix: portal auth setting - #7762
Conversation
| :label="LOGIN_METHOD_LABELS[loginMethodOption.value as LoginMethod] || loginMethodOption.label" | ||
| /> | ||
| </el-select> | ||
| </el-form-item> |
There was a problem hiding this comment.
Here's my review of the diff:
Issues & Concerns
-
Redundant fallback logic —
LOGIN_METHOD_LABELS[...] || loginMethodOption.labelsuggests uncertainty about whetherloginMethodOption.valueis a validLoginMethod. If it isn't, using it as an index is unsafe; if it is, the||fallback pollutes intent. Pick one source of truth. -
Unsafe type casting (
as LoginMethod) — repeated inline casts in the template obscure the real type ofloginMethodOption.value. Better to typeloginMethodOptions/defaultLoginMethodOptionscorrectly at their source (e.g.,Array<{ value: LoginMethod; label: string }>), then drop the casts. -
Inconsistent data sources — if
LOGIN_METHOD_LABELSis now the canonical label map, why keeplabelon the option objects at all? Maintaining labels in two places invites drift. Either:- Remove
labelfrom the options and rely solely onLOGIN_METHOD_LABELS, or - Generate the options from
LOGIN_METHOD_LABELS(single iteration overObject.entries).
- Remove
-
Missing-key behavior —
LOGIN_METHOD_LABELS[k] || labelsilently falls back when a key is missing. That may hide real bugs (e.g., a newLOGIN_METHODadded without a label). Consider??(nullish) instead of||— but note that if a label can legitimately be'', even??won't help; in that case use explicitinchecks or TypeScript exhaustiveness. -
Computed for label lookup (optimization) — if the checkbox/select lists are stable, precompute a mapped list once with
computed()rather than doing the dictionary lookup per-item per-render:const labeledLoginMethodOptions = computed(() => loginMethodOptions.map(o => ({ ...o, label: LOGIN_METHOD_LABELS[o.value] ?? o.label })) ) const labeledDefaultLoginMethodOptions = computed(() => defaultLoginMethodOptions.map(o => ({ ...o, label: LOGIN_METHOD_LABELS[o.value] ?? o.label })) )
Then iterate those in the template with no casts.
-
Logic duplication — the same "resolve label" logic appears twice. Extract into a helper:
const resolveLabel = (opt: { value: LoginMethod; label: string }) => LOGIN_METHOD_LABELS[opt.value] ?? opt.label
-
Ensure
LoginMethodandLOGIN_METHOD_LABELSstay in sync — defineLOGIN_METHOD_LABELSasRecord<LoginMethod, string>so TypeScript enforces exhaustiveness. This removes the need for the cast entirely. -
Import location consistency —
LOGIN_METHODcomes from@/api/enumsbutLOGIN_METHOD_LABELScomes from@/constants. Consider co-locating them (both in enums, or both in constants) to avoid future divergence. -
Minor: blank line / diff noise — the diff looks clean otherwise; no unrelated changes detected.
Suggested Rewrite (sketch)
// types
export const LOGIN_METHOD_LABELS: Record<LoginMethod, string> = { /* ... */ }
// component
const labeledOptions = computed(() =>
loginMethodOptions.map(o => ({ ...o, label: LOGIN_METHOD_LABELS[o.value] }))
)<el-checkbox v-for="o in labeledOptions" :key="o.value" :value="o.value" class="w-32">
{{ o.label }}
</el-checkbox>This removes casts, removes duplication, enforces label coverage at compile time, and avoids per-render dictionary lookups.
| :label="LOGIN_METHOD_LABELS[loginMethodOption.value as LoginMethod] || loginMethodOption.label" | ||
| /> | ||
| </el-select> | ||
| </el-form-item> |
There was a problem hiding this comment.
Code Review
Potential Issues
-
Runtime lookup with type assertion (
as LoginMethod)LOGIN_METHOD_LABELS[loginMethodOption.value as LoginMethod] || loginMethodOption.label
loginMethodOption.valueis likely typed asstring/number, so theas LoginMethodcast is unsafe — it bypasses type checking rather than verifying membership.- If
loginMethodOption.valueisn't actually a key ofLOGIN_METHOD_LABELS, you getundefinedand fall back silently. That hides misconfigurations instead of surfacing them. - Better: type
loginMethodOptions/defaultLoginMethodOptionsas arrays keyed byLoginMethod(e.g.,Array<{ value: LoginMethod; label: string }>). Then no cast is needed and the compiler guarantees the key exists.
-
Repeated lookup logic in the template
The same expression appears twice. Templates re-evaluate on every render, soLOGIN_METHOD_LABELS[...]runs per item per render. This is minor but duplicated and noisy. -
Two sources of truth for labels
You now haveloginMethodOption.labelandLOGIN_METHOD_LABELS. The||fallback means the constant wins when present, but both must be kept in sync. Consider removinglabelfrom the option objects entirely and deriving display text solely fromLOGIN_METHOD_LABELS. -
Untyped import addition
LoginMethodwas added to the type import — confirm it's actually exported from@/api/types(the diff assumes so; a typo here breaks the build).
Optimization Suggestions
-
Centralize resolution in a helper/computed
const getLoginMethodLabel = (method: LoginMethod) => LOGIN_METHOD_LABELS[method] ?? method
Then use
{{ getLoginMethodLabel(option.value) }}— avoids casts, single place to change, easier to test. -
Precompute options with labels
BuildloginMethodOptionsas a computed that already maps values → labels:const loginMethodOptions = computed(() => rawOptions.map(o => ({ ...o, label: LOGIN_METHOD_LABELS[o.value] ?? o.label })) )
Removes template logic and dedupes both call sites.
-
Use
??instead of||
If a label could legitimately be an empty string,||would incorrectly fall back. Prefer nullish coalescing:LOGIN_METHOD_LABELS[value] ?? fallbackLabel
-
Explicitly type the record
EnsureLOGIN_METHOD_LABELSis declared asRecord<LoginMethod, string>. Then indexing with a properly typed value is checked at compile time, and missing keys become a type error — eliminating the need for runtime fallbacks.
Minor
<el-checkbox :value=...>— verify this is the correct prop for your Element Plus version (older versions usedlabelfor the bound value; newer ones usevalue). Mixed usage across the file (checkbox uses:value, select uses:value+label) is fine for current versions but worth double-checking against yourelement-plusversion.- No functional/regression concerns otherwise; changes are backward-compatible thanks to the
||fallback.
fix: portal auth setting