fix: duplicate options appearing in relationship where builder (#6557)
- enables reactStrictMode by default - enables reactCompiler by default - fixes cases where ID's set to 0 broke UI
This commit is contained in:
@@ -9,16 +9,12 @@ const withBundleAnalyzer = bundleAnalyzer({
|
|||||||
// eslint-disable-next-line no-restricted-exports
|
// eslint-disable-next-line no-restricted-exports
|
||||||
export default withBundleAnalyzer(
|
export default withBundleAnalyzer(
|
||||||
withPayload({
|
withPayload({
|
||||||
reactStrictMode: false,
|
|
||||||
eslint: {
|
eslint: {
|
||||||
ignoreDuringBuilds: true,
|
ignoreDuringBuilds: true,
|
||||||
},
|
},
|
||||||
typescript: {
|
typescript: {
|
||||||
ignoreBuildErrors: true,
|
ignoreBuildErrors: true,
|
||||||
},
|
},
|
||||||
experimental: {
|
|
||||||
reactCompiler: false,
|
|
||||||
},
|
|
||||||
async redirects() {
|
async redirects() {
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -518,7 +518,10 @@ export const relationship: Validate<
|
|||||||
required,
|
required,
|
||||||
} = options
|
} = options
|
||||||
|
|
||||||
if ((!value || (Array.isArray(value) && value.length === 0)) && required) {
|
if (
|
||||||
|
((!value && typeof value !== 'number') || (Array.isArray(value) && value.length === 0)) &&
|
||||||
|
required
|
||||||
|
) {
|
||||||
return t('validation:required')
|
return t('validation:required')
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -551,7 +554,7 @@ export const relationship: Validate<
|
|||||||
collectionSlug = relationTo
|
collectionSlug = relationTo
|
||||||
|
|
||||||
// custom id
|
// custom id
|
||||||
if (val) {
|
if (val || typeof val === 'number') {
|
||||||
requestedID = val
|
requestedID = val
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
23
packages/ui/src/elements/ReactSelect/Input/index.tsx
Normal file
23
packages/ui/src/elements/ReactSelect/Input/index.tsx
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
'use client'
|
||||||
|
import type { ControlProps } from 'react-select'
|
||||||
|
|
||||||
|
import React from 'react'
|
||||||
|
import { components as SelectComponents } from 'react-select'
|
||||||
|
|
||||||
|
import type { Option } from '../types.js'
|
||||||
|
|
||||||
|
export const Input: React.FC<ControlProps<Option, any>> = (props) => {
|
||||||
|
return (
|
||||||
|
<React.Fragment>
|
||||||
|
{/* @ts-expect-error // TODO Fix this - Broke with React 19 types */}
|
||||||
|
<SelectComponents.Input
|
||||||
|
{...props}
|
||||||
|
/**
|
||||||
|
* Adding `aria-activedescendant` fixes hydration error
|
||||||
|
* source: https://github.com/JedWatson/react-select/issues/5459#issuecomment-1878037196
|
||||||
|
*/
|
||||||
|
aria-activedescendant={undefined}
|
||||||
|
/>
|
||||||
|
</React.Fragment>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -17,6 +17,7 @@ import { ShimmerEffect } from '../ShimmerEffect/index.js'
|
|||||||
import { ClearIndicator } from './ClearIndicator/index.js'
|
import { ClearIndicator } from './ClearIndicator/index.js'
|
||||||
import { Control } from './Control/index.js'
|
import { Control } from './Control/index.js'
|
||||||
import { DropdownIndicator } from './DropdownIndicator/index.js'
|
import { DropdownIndicator } from './DropdownIndicator/index.js'
|
||||||
|
import { Input } from './Input/index.js'
|
||||||
import { MultiValue, generateMultiValueDraggableID } from './MultiValue/index.js'
|
import { MultiValue, generateMultiValueDraggableID } from './MultiValue/index.js'
|
||||||
import { MultiValueLabel } from './MultiValueLabel/index.js'
|
import { MultiValueLabel } from './MultiValueLabel/index.js'
|
||||||
import { MultiValueRemove } from './MultiValueRemove/index.js'
|
import { MultiValueRemove } from './MultiValueRemove/index.js'
|
||||||
@@ -85,6 +86,7 @@ const SelectAdapter: React.FC<ReactSelectAdapterProps> = (props) => {
|
|||||||
ClearIndicator,
|
ClearIndicator,
|
||||||
Control,
|
Control,
|
||||||
DropdownIndicator,
|
DropdownIndicator,
|
||||||
|
Input,
|
||||||
MultiValue,
|
MultiValue,
|
||||||
MultiValueLabel,
|
MultiValueLabel,
|
||||||
MultiValueRemove,
|
MultiValueRemove,
|
||||||
@@ -157,6 +159,7 @@ const SelectAdapter: React.FC<ReactSelectAdapterProps> = (props) => {
|
|||||||
ClearIndicator,
|
ClearIndicator,
|
||||||
Control,
|
Control,
|
||||||
DropdownIndicator,
|
DropdownIndicator,
|
||||||
|
Input,
|
||||||
MultiValue,
|
MultiValue,
|
||||||
MultiValueLabel,
|
MultiValueLabel,
|
||||||
MultiValueRemove,
|
MultiValueRemove,
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ export const RelationshipCell: React.FC<RelationshipCellProps> = ({
|
|||||||
const isAboveViewport = canUseDOM ? entry?.boundingClientRect?.top < window.innerHeight : false
|
const isAboveViewport = canUseDOM ? entry?.boundingClientRect?.top < window.innerHeight : false
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (cellData && isAboveViewport && !hasRequested) {
|
if ((cellData || typeof cellData === 'number') && isAboveViewport && !hasRequested) {
|
||||||
const formattedValues: Value[] = []
|
const formattedValues: Value[] = []
|
||||||
const arrayCellData = Array.isArray(cellData) ? cellData : [cellData]
|
const arrayCellData = Array.isArray(cellData) ? cellData : [cellData]
|
||||||
arrayCellData
|
arrayCellData
|
||||||
|
|||||||
@@ -1,11 +1,13 @@
|
|||||||
'use client'
|
'use client'
|
||||||
/* eslint-disable @typescript-eslint/no-floating-promises */
|
/* eslint-disable @typescript-eslint/no-floating-promises */
|
||||||
import type { PaginatedDocs } from 'payload/database'
|
import type { PaginatedDocs } from 'payload/database'
|
||||||
|
import type { Where } from 'payload/types'
|
||||||
|
|
||||||
|
import QueryString from 'qs'
|
||||||
import React, { useCallback, useEffect, useReducer, useState } from 'react'
|
import React, { useCallback, useEffect, useReducer, useState } from 'react'
|
||||||
|
|
||||||
import type { Option } from '../../../ReactSelect/types.js'
|
import type { Option } from '../../../ReactSelect/types.js'
|
||||||
import type { GetResults, Props, ValueWithRelation } from './types.js'
|
import type { Props, ValueWithRelation } from './types.js'
|
||||||
|
|
||||||
import { useDebounce } from '../../../../hooks/useDebounce.js'
|
import { useDebounce } from '../../../../hooks/useDebounce.js'
|
||||||
import { useConfig } from '../../../../providers/Config/index.js'
|
import { useConfig } from '../../../../providers/Config/index.js'
|
||||||
@@ -29,13 +31,21 @@ export const RelationshipField: React.FC<Props> = (props) => {
|
|||||||
|
|
||||||
const hasMultipleRelations = Array.isArray(relationTo)
|
const hasMultipleRelations = Array.isArray(relationTo)
|
||||||
const [options, dispatchOptions] = useReducer(optionsReducer, [])
|
const [options, dispatchOptions] = useReducer(optionsReducer, [])
|
||||||
const [lastFullyLoadedRelation, setLastFullyLoadedRelation] = useState(-1)
|
|
||||||
const [lastLoadedPage, setLastLoadedPage] = useState(1)
|
|
||||||
const [search, setSearch] = useState('')
|
const [search, setSearch] = useState('')
|
||||||
const [errorLoading, setErrorLoading] = useState('')
|
const [errorLoading, setErrorLoading] = useState('')
|
||||||
const [hasLoadedFirstOptions, setHasLoadedFirstOptions] = useState(false)
|
const [hasLoadedFirstOptions, setHasLoadedFirstOptions] = useState(false)
|
||||||
const debouncedSearch = useDebounce(search, 300)
|
const debouncedSearch = useDebounce(search, 300)
|
||||||
const { i18n, t } = useTranslation()
|
const { i18n, t } = useTranslation()
|
||||||
|
const relationSlugs = hasMultipleRelations ? relationTo : [relationTo]
|
||||||
|
const initialRelationMap = () => {
|
||||||
|
const map: Map<string, number> = new Map()
|
||||||
|
relationSlugs.forEach((relation) => {
|
||||||
|
map.set(relation, 1)
|
||||||
|
})
|
||||||
|
return map
|
||||||
|
}
|
||||||
|
const nextPageByRelationshipRef = React.useRef<Map<string, number>>(initialRelationMap())
|
||||||
|
const partiallyLoadedRelationshipSlugs = React.useRef<string[]>(relationSlugs)
|
||||||
|
|
||||||
const addOptions = useCallback(
|
const addOptions = useCallback(
|
||||||
(data, relation) => {
|
(data, relation) => {
|
||||||
@@ -45,71 +55,94 @@ export const RelationshipField: React.FC<Props> = (props) => {
|
|||||||
[collections, hasMultipleRelations, i18n],
|
[collections, hasMultipleRelations, i18n],
|
||||||
)
|
)
|
||||||
|
|
||||||
const getResults = useCallback<GetResults>(
|
const loadRelationOptions = React.useCallback(
|
||||||
async ({
|
async ({
|
||||||
lastFullyLoadedRelation: lastFullyLoadedRelationArg,
|
abortController,
|
||||||
lastLoadedPage: lastLoadedPageArg,
|
relationSlug,
|
||||||
search: searchArg,
|
}: {
|
||||||
// eslint-disable-next-line @typescript-eslint/require-await
|
abortController: AbortController
|
||||||
|
relationSlug: string
|
||||||
}) => {
|
}) => {
|
||||||
let lastLoadedPageToUse = typeof lastLoadedPageArg !== 'undefined' ? lastLoadedPageArg : 1
|
const collection = collections.find((coll) => coll.slug === relationSlug)
|
||||||
const lastFullyLoadedRelationToUse =
|
const fieldToSearch = collection?.admin?.useAsTitle || 'id'
|
||||||
typeof lastFullyLoadedRelationArg !== 'undefined' ? lastFullyLoadedRelationArg : -1
|
const pageIndex = nextPageByRelationshipRef.current.get(relationSlug)
|
||||||
|
|
||||||
const relations = Array.isArray(relationTo) ? relationTo : [relationTo]
|
if (partiallyLoadedRelationshipSlugs.current.includes(relationSlug)) {
|
||||||
const relationsToFetch =
|
const query: {
|
||||||
lastFullyLoadedRelationToUse === -1
|
depth?: number
|
||||||
? relations
|
limit?: number
|
||||||
: relations.slice(lastFullyLoadedRelationToUse + 1)
|
page?: number
|
||||||
|
where: Where
|
||||||
|
} = {
|
||||||
|
depth: 0,
|
||||||
|
limit: maxResultsPerRequest,
|
||||||
|
page: pageIndex,
|
||||||
|
where: {
|
||||||
|
and: [],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
let resultsFetched = 0
|
if (debouncedSearch) {
|
||||||
|
query.where.and.push({
|
||||||
|
[fieldToSearch]: {
|
||||||
|
like: debouncedSearch,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
if (!errorLoading) {
|
try {
|
||||||
relationsToFetch.reduce(async (priorRelation, relation) => {
|
const response = await fetch(
|
||||||
await priorRelation
|
`${serverURL}${api}/${relationSlug}${QueryString.stringify(query, { addQueryPrefix: true })}`,
|
||||||
|
{
|
||||||
if (resultsFetched < 10) {
|
credentials: 'include',
|
||||||
const collection = collections.find((coll) => coll.slug === relation)
|
headers: {
|
||||||
const fieldToSearch = collection?.admin?.useAsTitle || 'id'
|
'Accept-Language': i18n.language,
|
||||||
const searchParam = searchArg ? `&where[${fieldToSearch}][like]=${searchArg}` : ''
|
|
||||||
|
|
||||||
const response = await fetch(
|
|
||||||
`${serverURL}${api}/${relation}?limit=${maxResultsPerRequest}&page=${lastLoadedPageToUse}&depth=0${searchParam}`,
|
|
||||||
{
|
|
||||||
credentials: 'include',
|
|
||||||
headers: {
|
|
||||||
'Accept-Language': i18n.language,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
)
|
signal: abortController.signal,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
if (response.ok) {
|
if (response.ok) {
|
||||||
const data: PaginatedDocs = await response.json()
|
const data: PaginatedDocs = await response.json()
|
||||||
if (data.docs.length > 0) {
|
if (data.docs.length > 0) {
|
||||||
resultsFetched += data.docs.length
|
addOptions(data, relationSlug)
|
||||||
addOptions(data, relation)
|
|
||||||
setLastLoadedPage(data.page)
|
|
||||||
|
|
||||||
if (!data.nextPage) {
|
if (!debouncedSearch) {
|
||||||
setLastFullyLoadedRelation(relations.indexOf(relation))
|
if (data.nextPage) {
|
||||||
|
nextPageByRelationshipRef.current.set(relationSlug, data.nextPage)
|
||||||
// If there are more relations to search, need to reset lastLoadedPage to 1
|
} else {
|
||||||
// both locally within function and state
|
partiallyLoadedRelationshipSlugs.current =
|
||||||
if (relations.indexOf(relation) + 1 < relations.length) {
|
partiallyLoadedRelationshipSlugs.current.filter(
|
||||||
lastLoadedPageToUse = 1
|
(partiallyLoadedRelation) => partiallyLoadedRelation !== relationSlug,
|
||||||
}
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
setErrorLoading(t('error:unspecific'))
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
setErrorLoading(t('error:unspecific'))
|
||||||
}
|
}
|
||||||
}, Promise.resolve())
|
} catch (e) {
|
||||||
|
if (!abortController.signal.aborted) {
|
||||||
|
console.error(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setHasLoadedFirstOptions(true)
|
||||||
},
|
},
|
||||||
[i18n, relationTo, errorLoading, collections, serverURL, api, addOptions, t],
|
[addOptions, api, collections, debouncedSearch, i18n.language, serverURL, t],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const loadMoreOptions = React.useCallback(() => {
|
||||||
|
if (partiallyLoadedRelationshipSlugs.current.length > 0) {
|
||||||
|
const abortController = new AbortController()
|
||||||
|
loadRelationOptions({
|
||||||
|
abortController,
|
||||||
|
relationSlug: partiallyLoadedRelationshipSlugs.current[0],
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}, [loadRelationOptions])
|
||||||
|
|
||||||
const findOptionsByValue = useCallback((): Option | Option[] => {
|
const findOptionsByValue = useCallback((): Option | Option[] => {
|
||||||
if (value) {
|
if (value) {
|
||||||
if (hasMany) {
|
if (hasMany) {
|
||||||
@@ -198,27 +231,34 @@ export const RelationshipField: React.FC<Props> = (props) => {
|
|||||||
[i18n, addOptions, api, errorLoading, serverURL, t],
|
[i18n, addOptions, api, errorLoading, serverURL, t],
|
||||||
)
|
)
|
||||||
|
|
||||||
// ///////////////////////////
|
/**
|
||||||
// Get results when search input changes
|
* 1. Trigger initial relationship options fetch
|
||||||
// ///////////////////////////
|
* 2. When search changes, loadRelationOptions will
|
||||||
|
* fire off again
|
||||||
|
*/
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
dispatchOptions({
|
const relations = Array.isArray(relationTo) ? relationTo : [relationTo]
|
||||||
type: 'CLEAR',
|
const abortControllers: AbortController[] = []
|
||||||
i18n,
|
relations.forEach((relation) => {
|
||||||
required: true,
|
const abortController = new AbortController()
|
||||||
|
loadRelationOptions({
|
||||||
|
abortController,
|
||||||
|
relationSlug: relation,
|
||||||
|
})
|
||||||
|
abortControllers.push(abortController)
|
||||||
})
|
})
|
||||||
|
|
||||||
setHasLoadedFirstOptions(true)
|
return () => {
|
||||||
setLastLoadedPage(1)
|
abortControllers.forEach((controller) => {
|
||||||
setLastFullyLoadedRelation(-1)
|
if (controller.signal) controller.abort()
|
||||||
getResults({ search: debouncedSearch })
|
})
|
||||||
}, [getResults, debouncedSearch, relationTo, i18n])
|
}
|
||||||
|
}, [i18n, loadRelationOptions, relationTo])
|
||||||
// ///////////////////////////
|
|
||||||
// Format options once first options have been retrieved
|
|
||||||
// ///////////////////////////
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load any options that were not returned
|
||||||
|
* in the first 10 of each relation fetch
|
||||||
|
*/
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (value && hasLoadedFirstOptions) {
|
if (value && hasLoadedFirstOptions) {
|
||||||
if (hasMany) {
|
if (hasMany) {
|
||||||
@@ -299,9 +339,7 @@ export const RelationshipField: React.FC<Props> = (props) => {
|
|||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
onInputChange={handleInputChange}
|
onInputChange={handleInputChange}
|
||||||
onMenuScrollToBottom={() => {
|
onMenuScrollToBottom={loadMoreOptions}
|
||||||
getResults({ lastFullyLoadedRelation, lastLoadedPage: lastLoadedPage + 1 })
|
|
||||||
}}
|
|
||||||
options={options}
|
options={options}
|
||||||
placeholder={t('general:selectValue')}
|
placeholder={t('general:selectValue')}
|
||||||
value={valueToRender}
|
value={valueToRender}
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ export const Condition: React.FC<Props> = (props) => {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// This is to trigger changes when the debounced value changes
|
// This is to trigger changes when the debounced value changes
|
||||||
if (
|
if (
|
||||||
internalField.value &&
|
(internalField?.value || typeof internalField?.value === 'number') &&
|
||||||
internalOperatorOption &&
|
internalOperatorOption &&
|
||||||
![null, undefined].includes(debouncedValue)
|
![null, undefined].includes(debouncedValue)
|
||||||
) {
|
) {
|
||||||
@@ -130,12 +130,12 @@ export const Condition: React.FC<Props> = (props) => {
|
|||||||
setInternalQueryValue(undefined)
|
setInternalQueryValue(undefined)
|
||||||
}}
|
}}
|
||||||
options={fields}
|
options={fields}
|
||||||
value={fields.find((field) => internalField.value === field.value) || fields[0]}
|
value={fields.find((field) => internalField?.value === field.value) || fields[0]}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className={`${baseClass}__operator`}>
|
<div className={`${baseClass}__operator`}>
|
||||||
<ReactSelect
|
<ReactSelect
|
||||||
disabled={!internalField.value}
|
disabled={!internalField?.value && typeof internalField?.value !== 'number'}
|
||||||
isClearable={false}
|
isClearable={false}
|
||||||
onChange={(operator) => {
|
onChange={(operator) => {
|
||||||
setInternalOperatorOption(operator.value)
|
setInternalOperatorOption(operator.value)
|
||||||
|
|||||||
@@ -86,9 +86,9 @@ export const WhereBuilder: React.FC<WhereBuilderProps> = (props) => {
|
|||||||
return []
|
return []
|
||||||
})
|
})
|
||||||
|
|
||||||
const addCondition = React.useCallback(({ andIndex, fieldName, orIndex, relation }) => {
|
const addCondition = React.useCallback(
|
||||||
setConditions((prevConditions) => {
|
({ andIndex, fieldName, orIndex, relation }) => {
|
||||||
const newConditions = [...prevConditions]
|
const newConditions = [...conditions]
|
||||||
if (relation === 'and') {
|
if (relation === 'and') {
|
||||||
newConditions[orIndex].and.splice(andIndex, 0, { [fieldName]: {} })
|
newConditions[orIndex].and.splice(andIndex, 0, { [fieldName]: {} })
|
||||||
} else {
|
} else {
|
||||||
@@ -100,46 +100,45 @@ export const WhereBuilder: React.FC<WhereBuilderProps> = (props) => {
|
|||||||
],
|
],
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
setConditions(newConditions)
|
||||||
return newConditions
|
},
|
||||||
})
|
[conditions],
|
||||||
}, [])
|
)
|
||||||
|
|
||||||
const updateCondition = React.useCallback(
|
const updateCondition = React.useCallback(
|
||||||
({ andIndex, fieldName: fieldNameArg, operator: operatorArg, orIndex, value: valueArg }) => {
|
({ andIndex, fieldName, operator, orIndex, value: valueArg }) => {
|
||||||
setConditions((prevConditions) => {
|
const existingRowCondition = conditions[orIndex].and[andIndex]
|
||||||
const newConditions = [...prevConditions]
|
if (typeof existingRowCondition === 'object' && fieldName && operator) {
|
||||||
if (typeof newConditions[orIndex].and[andIndex] === 'object') {
|
const value = valueArg ?? (operator ? existingRowCondition[operator] : '')
|
||||||
const fieldName = fieldNameArg
|
const newRowCondition = {
|
||||||
const operator = operatorArg
|
[fieldName]: operator ? { [operator]: value } : {},
|
||||||
const value = valueArg ?? (operator ? newConditions[orIndex].and[andIndex][operator] : '')
|
}
|
||||||
|
|
||||||
if (fieldName && operator && ![null, undefined].includes(value)) {
|
if (JSON.stringify(existingRowCondition) !== JSON.stringify(newRowCondition)) {
|
||||||
newConditions[orIndex].and[andIndex] = {
|
conditions[orIndex].and[andIndex] = newRowCondition
|
||||||
[fieldName]: operator ? { [operator]: value } : {},
|
setConditions(conditions)
|
||||||
}
|
if (![null, undefined].includes(value)) {
|
||||||
|
// only update query when field/operator/value are filled out
|
||||||
setShouldUpdateQuery(true)
|
setShouldUpdateQuery(true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return newConditions
|
|
||||||
})
|
|
||||||
},
|
},
|
||||||
[],
|
[conditions],
|
||||||
)
|
)
|
||||||
|
|
||||||
const removeCondition = React.useCallback(({ andIndex, orIndex }) => {
|
const removeCondition = React.useCallback(
|
||||||
setConditions((prevConditions) => {
|
({ andIndex, orIndex }) => {
|
||||||
const newConditions = [...prevConditions]
|
const newConditions = [...conditions]
|
||||||
newConditions[orIndex].and.splice(andIndex, 1)
|
newConditions[orIndex].and.splice(andIndex, 1)
|
||||||
if (newConditions[orIndex].and.length === 0) {
|
if (newConditions[orIndex].and.length === 0) {
|
||||||
newConditions.splice(orIndex, 1)
|
newConditions.splice(orIndex, 1)
|
||||||
}
|
}
|
||||||
|
setConditions(newConditions)
|
||||||
return newConditions
|
setShouldUpdateQuery(true)
|
||||||
})
|
},
|
||||||
setShouldUpdateQuery(true)
|
[conditions],
|
||||||
}, [])
|
)
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
if (shouldUpdateQuery) {
|
if (shouldUpdateQuery) {
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ type Args = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const findOptionsByValue = ({ options, value }: Args): Option | Option[] => {
|
export const findOptionsByValue = ({ options, value }: Args): Option | Option[] => {
|
||||||
if (value) {
|
if (value || typeof value === 'number') {
|
||||||
if (Array.isArray(value)) {
|
if (Array.isArray(value)) {
|
||||||
return value.map((val) => {
|
return value.map((val) => {
|
||||||
let matchedOption: Option
|
let matchedOption: Option
|
||||||
|
|||||||
Reference in New Issue
Block a user