Refactor SimplePropertyFilter for improved key handling and filtering logic
Some checks failed
farmcontrol/farmcontrol-ui/pipeline/head There was a failure building this commit
Some checks failed
farmcontrol/farmcontrol-ui/pipeline/head There was a failure building this commit
- Enhanced the getOptionKey function to support object types and improve key generation for options. - Updated local state management to utilize keys for checked values, ensuring consistent behavior during filtering. - Refactored handleChange and emitChange functions to work with keys, improving clarity and maintainability. - Adjusted Checkbox component to use generated keys for value handling, enhancing the filtering experience.
This commit is contained in:
parent
0b110cdfff
commit
38e89e45c7
@ -2,13 +2,21 @@ import { useState, useEffect, useContext, useMemo } from 'react'
|
|||||||
import { Flex, Checkbox, Spin, Typography } from 'antd'
|
import { Flex, Checkbox, Spin, Typography } from 'antd'
|
||||||
import PropTypes from 'prop-types'
|
import PropTypes from 'prop-types'
|
||||||
import { ApiServerContext } from '../context/ApiServerContext'
|
import { ApiServerContext } from '../context/ApiServerContext'
|
||||||
import { getModelProperties } from '../../../database/ObjectModels'
|
import {
|
||||||
|
getModelByName,
|
||||||
|
getModelProperties
|
||||||
|
} from '../../../database/ObjectModels'
|
||||||
import ObjectProperty from './ObjectProperty'
|
import ObjectProperty from './ObjectProperty'
|
||||||
import { LoadingOutlined } from '@ant-design/icons'
|
import { LoadingOutlined } from '@ant-design/icons'
|
||||||
const { Text } = Typography
|
const { Text } = Typography
|
||||||
|
|
||||||
const getOptionKey = (option) => {
|
const getOptionKey = (option) => {
|
||||||
if (option && typeof option === 'object') {
|
if (option && typeof option === 'object') {
|
||||||
|
if (option.objectType) {
|
||||||
|
const { prefix } = getModelByName(option.objectType)
|
||||||
|
if (option._reference != null) return `${prefix}:${option._reference}`
|
||||||
|
if (option._id != null) return `${prefix}:${option._id}`
|
||||||
|
}
|
||||||
return String(option._id ?? option.type ?? JSON.stringify(option))
|
return String(option._id ?? option.type ?? JSON.stringify(option))
|
||||||
}
|
}
|
||||||
return String(option)
|
return String(option)
|
||||||
@ -86,9 +94,12 @@ const SimplePropertyFilter = ({
|
|||||||
if (options.length === 0) return
|
if (options.length === 0) return
|
||||||
if (value?.length > 0) {
|
if (value?.length > 0) {
|
||||||
const matched = matchOptions(options, value)
|
const matched = matchOptions(options, value)
|
||||||
setLocalChecked(matched.length > 0 ? matched : [...value])
|
const matchedKeys = matched.map(getOptionKey)
|
||||||
|
setLocalChecked(
|
||||||
|
matchedKeys.length > 0 ? matchedKeys : value.map(getOptionKey)
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
setLocalChecked(options)
|
setLocalChecked(options.map(getOptionKey))
|
||||||
}
|
}
|
||||||
// valueKey captures value contents; value is read for matching
|
// valueKey captures value contents; value is read for matching
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
@ -102,43 +113,44 @@ const SimplePropertyFilter = ({
|
|||||||
)
|
)
|
||||||
}, [options, search])
|
}, [options, search])
|
||||||
|
|
||||||
const checkedValues = localChecked ?? options
|
const optionKeys = useMemo(() => options.map(getOptionKey), [options])
|
||||||
|
const checkedKeys = localChecked ?? optionKeys
|
||||||
|
|
||||||
const emitChange = (next) => {
|
const emitChange = (nextKeys) => {
|
||||||
setLocalChecked(next)
|
setLocalChecked(nextKeys)
|
||||||
// All selected (or empty options) means no filter applied
|
// All selected (or empty options) means no filter applied
|
||||||
if (options.length > 0 && next.length === options.length) {
|
if (optionKeys.length > 0 && nextKeys.length === optionKeys.length) {
|
||||||
onChange?.([])
|
onChange?.([])
|
||||||
} else {
|
} else {
|
||||||
onChange?.(next)
|
onChange?.(nextKeys)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleChange = (visibleChecked) => {
|
const handleChange = (visibleCheckedKeys) => {
|
||||||
const hiddenSelected = checkedValues.filter(
|
const filteredKeys = new Set(filteredOptions.map(getOptionKey))
|
||||||
(checked) =>
|
const hiddenSelected = checkedKeys.filter((key) => !filteredKeys.has(key))
|
||||||
!filteredOptions.some(
|
emitChange([...hiddenSelected, ...visibleCheckedKeys])
|
||||||
(option) => getOptionKey(option) === getOptionKey(checked)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
emitChange([...hiddenSelected, ...visibleChecked])
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Spin spinning={loading} indicator={<LoadingOutlined spin />}>
|
<Spin spinning={loading} indicator={<LoadingOutlined spin />}>
|
||||||
<Checkbox.Group
|
<Checkbox.Group
|
||||||
value={checkedValues}
|
value={checkedKeys}
|
||||||
onChange={handleChange}
|
onChange={handleChange}
|
||||||
style={{ width: '100%' }}
|
style={{ width: '100%' }}
|
||||||
>
|
>
|
||||||
<Flex vertical gap={16} style={{ minWidth: 0 }}>
|
<Flex vertical gap={16} style={{ minWidth: 0 }}>
|
||||||
{filteredOptions.map((option) => (
|
{filteredOptions.map((option) => (
|
||||||
<Flex gap={14} key={getOptionKey(option)} align='center'>
|
<Flex gap={14} key={getOptionKey(option)} align='center'>
|
||||||
<Checkbox value={option} style={{ minWidth: 0 }}></Checkbox>
|
<Checkbox
|
||||||
|
value={getOptionKey(option)}
|
||||||
|
style={{ minWidth: 0 }}
|
||||||
|
></Checkbox>
|
||||||
<div style={{ minWidth: 0 }}>
|
<div style={{ minWidth: 0 }}>
|
||||||
{property ? (
|
{property ? (
|
||||||
<ObjectProperty
|
<ObjectProperty
|
||||||
{...property}
|
{...property}
|
||||||
|
objectType={option?.objectType ?? property.objectType}
|
||||||
modelType={modelType}
|
modelType={modelType}
|
||||||
value={getDisplayValue(option, property)}
|
value={getDisplayValue(option, property)}
|
||||||
inTable={true}
|
inTable={true}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user