From 38e89e45c73743a54bc9022894784bce4001a985 Mon Sep 17 00:00:00 2001 From: Tom Butcher Date: Mon, 10 Aug 2026 00:56:55 +0100 Subject: [PATCH] Refactor SimplePropertyFilter for improved key handling and filtering logic - 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. --- .../Dashboard/common/SimplePropertyFilter.jsx | 48 ++++++++++++------- 1 file changed, 30 insertions(+), 18 deletions(-) diff --git a/src/components/Dashboard/common/SimplePropertyFilter.jsx b/src/components/Dashboard/common/SimplePropertyFilter.jsx index 7c98e16..0954419 100644 --- a/src/components/Dashboard/common/SimplePropertyFilter.jsx +++ b/src/components/Dashboard/common/SimplePropertyFilter.jsx @@ -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 ( }> {filteredOptions.map((option) => ( - +
{property ? (