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 PropTypes from 'prop-types'
|
||||
import { ApiServerContext } from '../context/ApiServerContext'
|
||||
import { getModelProperties } from '../../../database/ObjectModels'
|
||||
import {
|
||||
getModelByName,
|
||||
getModelProperties
|
||||
} from '../../../database/ObjectModels'
|
||||
import ObjectProperty from './ObjectProperty'
|
||||
import { LoadingOutlined } from '@ant-design/icons'
|
||||
const { Text } = Typography
|
||||
|
||||
const getOptionKey = (option) => {
|
||||
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)
|
||||
@ -86,9 +94,12 @@ const SimplePropertyFilter = ({
|
||||
if (options.length === 0) return
|
||||
if (value?.length > 0) {
|
||||
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 {
|
||||
setLocalChecked(options)
|
||||
setLocalChecked(options.map(getOptionKey))
|
||||
}
|
||||
// valueKey captures value contents; value is read for matching
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
@ -102,43 +113,44 @@ const SimplePropertyFilter = ({
|
||||
)
|
||||
}, [options, search])
|
||||
|
||||
const checkedValues = localChecked ?? options
|
||||
const optionKeys = useMemo(() => options.map(getOptionKey), [options])
|
||||
const checkedKeys = localChecked ?? optionKeys
|
||||
|
||||
const emitChange = (next) => {
|
||||
setLocalChecked(next)
|
||||
const emitChange = (nextKeys) => {
|
||||
setLocalChecked(nextKeys)
|
||||
// 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?.([])
|
||||
} else {
|
||||
onChange?.(next)
|
||||
onChange?.(nextKeys)
|
||||
}
|
||||
}
|
||||
|
||||
const handleChange = (visibleChecked) => {
|
||||
const hiddenSelected = checkedValues.filter(
|
||||
(checked) =>
|
||||
!filteredOptions.some(
|
||||
(option) => getOptionKey(option) === getOptionKey(checked)
|
||||
)
|
||||
)
|
||||
emitChange([...hiddenSelected, ...visibleChecked])
|
||||
const handleChange = (visibleCheckedKeys) => {
|
||||
const filteredKeys = new Set(filteredOptions.map(getOptionKey))
|
||||
const hiddenSelected = checkedKeys.filter((key) => !filteredKeys.has(key))
|
||||
emitChange([...hiddenSelected, ...visibleCheckedKeys])
|
||||
}
|
||||
|
||||
return (
|
||||
<Spin spinning={loading} indicator={<LoadingOutlined spin />}>
|
||||
<Checkbox.Group
|
||||
value={checkedValues}
|
||||
value={checkedKeys}
|
||||
onChange={handleChange}
|
||||
style={{ width: '100%' }}
|
||||
>
|
||||
<Flex vertical gap={16} style={{ minWidth: 0 }}>
|
||||
{filteredOptions.map((option) => (
|
||||
<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 }}>
|
||||
{property ? (
|
||||
<ObjectProperty
|
||||
{...property}
|
||||
objectType={option?.objectType ?? property.objectType}
|
||||
modelType={modelType}
|
||||
value={getDisplayValue(option, property)}
|
||||
inTable={true}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user