Skip to content

Commit 821bae4

Browse files
committed
perf(ui): short-circuit form-state processing for fields failing admin.condition
Previously only the render call was gated on passesCondition; the switch still ran filterOptions resolves (DB queries on relationship/upload), blocks validation, and full recursion into hidden subtrees. Add an early-exit guard so a failing condition writes a minimal state entry and returns, skipping access checks, validation, switch processing, filterOptions, and child iteration. The client re-requests form state on condition flips, so the minimal entry is sufficient.
1 parent 4f7ac05 commit 821bae4

1 file changed

Lines changed: 17 additions & 9 deletions

File tree

packages/ui/src/forms/fieldSchemasToFormState/addFieldStatePromise.ts

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,17 @@ export const addFieldStatePromise = async (args: AddFieldStatePromiseArgs): Prom
184184
fieldState.fieldSchema = field
185185
}
186186

187+
// Short-circuit when the field fails its condition: skip access checks,
188+
// validation, switch processing, recursion into children, filterOptions
189+
// resolution, and render. The client re-requests form state when conditions
190+
// flip, so a minimal entry is sufficient here.
191+
if (passesCondition === false) {
192+
if (!filter || filter(args)) {
193+
state[path] = fieldState
194+
}
195+
return
196+
}
197+
187198
if (fieldAffectsData(field) && !fieldIsHiddenOrDisabled(field) && field.type !== 'tab') {
188199
fieldPermissions =
189200
parentPermissions === true
@@ -808,10 +819,6 @@ export const addFieldStatePromise = async (args: AddFieldStatePromiseArgs): Prom
808819
state[path] = {
809820
disableFormData: true,
810821
}
811-
812-
if (passesCondition === false) {
813-
state[path].passesCondition = false
814-
}
815822
}
816823

817824
await iterateFields({
@@ -893,11 +900,12 @@ export const addFieldStatePromise = async (args: AddFieldStatePromiseArgs): Prom
893900

894901
const pathSegments = path ? path.split('.') : []
895902

896-
// If passesCondition is false then this should always result to false
897-
// If the tab has no admin.condition provided then fallback to passesCondition and let that decide the result
898-
let tabPassesCondition = passesCondition
903+
// The incoming `passesCondition` is guaranteed to be true here because the
904+
// function returns early when it is false. Tab visibility is determined
905+
// solely by its own `admin.condition`, if defined.
906+
let tabPassesCondition: boolean = true
899907

900-
if (passesCondition && typeof field.admin?.condition === 'function') {
908+
if (typeof field.admin?.condition === 'function') {
901909
tabPassesCondition = field.admin.condition(fullData, data, {
902910
blockData,
903911
operation,
@@ -986,7 +994,7 @@ export const addFieldStatePromise = async (args: AddFieldStatePromiseArgs): Prom
986994
}
987995
}
988996

989-
if (renderFieldFn && !fieldIsHiddenOrDisabled(field) && passesCondition !== false) {
997+
if (renderFieldFn && !fieldIsHiddenOrDisabled(field)) {
990998
const fieldConfig = fieldSchemaMap.get(schemaPath)
991999

9921000
if (!fieldConfig && !mockRSCs) {

0 commit comments

Comments
 (0)