fix(ui): uses query provider as single source of truth for where builder (#11476)
The "where" builder maintains its own duplicative state for conditions. This is problematic when an outside force needs to control the conditions in some way, but the "where" builder will not receive those updates. While it is a requirement of the "where" builder to transform the "where" query into "and" / "or" format for rendering, it does so in a way that causes it to become out of sync with the query provider. This is because we first initialize state from context, then for every change to conditions, report those updates to contexts—but not the other way around. To fix this, we need to completely remove state from the "where" builder and solely rely on the query context as a single source of truth. This will allow it to receive automatic updates from query provider without needing to sync both local state and context simultaneously. Now, we only ever need to send updates to the query provider and let the top-down rendering cycle propagate those changes everywhere.
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
'use client'
|
'use client'
|
||||||
import type { Operator, Where } from 'payload'
|
import type { Operator } from 'payload'
|
||||||
|
|
||||||
import { getTranslation } from '@payloadcms/translations'
|
import { getTranslation } from '@payloadcms/translations'
|
||||||
import React, { useMemo } from 'react'
|
import React, { useMemo } from 'react'
|
||||||
@@ -32,7 +32,7 @@ export const WhereBuilder: React.FC<WhereBuilderProps> = (props) => {
|
|||||||
|
|
||||||
const { handleWhereChange, query } = useListQuery()
|
const { handleWhereChange, query } = useListQuery()
|
||||||
|
|
||||||
const [conditions, setConditions] = React.useState<Where[]>(() => {
|
const conditions = useMemo(() => {
|
||||||
const whereFromSearch = query.where
|
const whereFromSearch = query.where
|
||||||
|
|
||||||
if (whereFromSearch) {
|
if (whereFromSearch) {
|
||||||
@@ -51,7 +51,7 @@ export const WhereBuilder: React.FC<WhereBuilderProps> = (props) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return []
|
return []
|
||||||
})
|
}, [query.where])
|
||||||
|
|
||||||
const addCondition: AddCondition = React.useCallback(
|
const addCondition: AddCondition = React.useCallback(
|
||||||
async ({ andIndex, field, orIndex, relation }) => {
|
async ({ andIndex, field, orIndex, relation }) => {
|
||||||
@@ -77,8 +77,7 @@ export const WhereBuilder: React.FC<WhereBuilderProps> = (props) => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
setConditions(newConditions)
|
await handleWhereChange({ or: newConditions })
|
||||||
await handleWhereChange({ or: conditions })
|
|
||||||
},
|
},
|
||||||
[conditions, handleWhereChange],
|
[conditions, handleWhereChange],
|
||||||
)
|
)
|
||||||
@@ -100,8 +99,7 @@ export const WhereBuilder: React.FC<WhereBuilderProps> = (props) => {
|
|||||||
const newConditions = [...conditions]
|
const newConditions = [...conditions]
|
||||||
newConditions[orIndex].and[andIndex] = newRowCondition
|
newConditions[orIndex].and[andIndex] = newRowCondition
|
||||||
|
|
||||||
setConditions(newConditions)
|
await handleWhereChange({ or: newConditions })
|
||||||
await handleWhereChange({ or: conditions })
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[conditions, handleWhereChange],
|
[conditions, handleWhereChange],
|
||||||
@@ -116,8 +114,7 @@ export const WhereBuilder: React.FC<WhereBuilderProps> = (props) => {
|
|||||||
newConditions.splice(orIndex, 1)
|
newConditions.splice(orIndex, 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
setConditions(newConditions)
|
await handleWhereChange({ or: newConditions })
|
||||||
await handleWhereChange({ or: conditions })
|
|
||||||
},
|
},
|
||||||
[conditions, handleWhereChange],
|
[conditions, handleWhereChange],
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -45,13 +45,6 @@ export const ListQueryProvider: React.FC<ListQueryProps> = ({
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
// If the search params change externally, update the current query
|
|
||||||
useEffect(() => {
|
|
||||||
if (modifySearchParams) {
|
|
||||||
setCurrentQuery(searchParams)
|
|
||||||
}
|
|
||||||
}, [searchParams, modifySearchParams])
|
|
||||||
|
|
||||||
const refineListData = useCallback(
|
const refineListData = useCallback(
|
||||||
// eslint-disable-next-line @typescript-eslint/require-await
|
// eslint-disable-next-line @typescript-eslint/require-await
|
||||||
async (query: ListQuery) => {
|
async (query: ListQuery) => {
|
||||||
|
|||||||
Reference in New Issue
Block a user