Enhance ObjectSelect component to support additional filtering and improved data handling

- Introduced a new 'masterFilter' prop to allow for more complex filtering scenarios.
- Updated data fetching logic to handle both array and object responses from the API, ensuring robust data management.
- Improved tree data handling by refining how children nodes are built and updated.
- Added a 'disabled' prop to control the component's interactivity.
- Enhanced prop types for better type checking and documentation clarity.
This commit is contained in:
Tom Butcher 2025-08-18 01:02:27 +01:00
parent 08dbbefada
commit e423f32493

View File

@ -9,6 +9,7 @@ import PropTypes from 'prop-types'
import { TreeSelect, Space, Button, Input } from 'antd'
import ReloadIcon from '../../Icons/ReloadIcon'
import { ApiServerContext } from '../context/ApiServerContext'
import { AuthContext } from '../context/AuthContext'
import ObjectProperty from './ObjectProperty'
import { getModelByName } from '../../../database/ObjectModels'
import merge from 'lodash/merge'
@ -20,10 +21,13 @@ const ObjectSelect = ({
multiple = false,
treeSelectProps = {},
filter = {},
masterFilter = {},
value,
disabled = false,
...rest
}) => {
const { fetchObjectsByProperty } = useContext(ApiServerContext)
const { token } = useContext(AuthContext)
// --- State ---
const [treeData, setTreeData] = useState([])
const [objectPropertiesTree, setObjectPropertiesTree] = useState({})
@ -40,9 +44,15 @@ const ObjectSelect = ({
try {
const data = await fetchObjectsByProperty(type, {
properties: properties,
filter: customFilter
filter: customFilter,
masterFilter
})
if (Array.isArray(data)) {
setObjectPropertiesTree((prev) => merge([], prev, data))
} else {
setObjectPropertiesTree((prev) => merge({}, prev, data))
}
setInitialLoading(false)
setError(false)
return data
@ -86,6 +96,7 @@ const ObjectSelect = ({
}
})
}
if (typeof data == 'object') {
const property = properties[pIdx] || null
return Object.entries(data)
@ -97,7 +108,7 @@ const ObjectSelect = ({
value: key,
key: parentKeys.concat(key).join(':'),
property,
parentKeys: parentKeys.concat(key),
parentKeys: parentKeys.concat(key || ':'),
filterPath: newFilterPath,
selectable: false,
children: buildTreeData(
@ -120,6 +131,7 @@ const ObjectSelect = ({
const loadData = async (node) => {
// node.property is the property name, node.value is the value
if (!node.property) return
// Build filter for this node by merging all parent property-value pairs
const customFilter = { ...filter }
if (Array.isArray(node.filterPath)) {
@ -128,12 +140,21 @@ const ObjectSelect = ({
})
}
customFilter[node.property] = node.value
// Fetch children for this node
const data = await handleFetchObjectsProperties(customFilter)
if (!data) return
// Build new children
// Extract only the children for the specific node that was expanded
let nodeSpecificData = data
if (typeof data === 'object' && !Array.isArray(data)) {
// If the API returns an object with multiple keys, get only the data for this node
nodeSpecificData = data[node.value] || {}
}
// Build new children only for this specific node
const children = buildTreeData(
data,
nodeSpecificData,
properties.indexOf(node.property) + 1,
node.parentKeys || [],
(node.filterPath || []).concat({
@ -141,7 +162,8 @@ const ObjectSelect = ({
value: node.value
})
)
// Update treeData with new children for this node
// Update treeData with new children for this node only
setTreeData((prevTreeData) => {
// Helper to recursively update the correct node
const updateNode = (nodes) =>
@ -195,11 +217,12 @@ const ObjectSelect = ({
// Build a new filter from value's properties that are in the properties list
const valueFilter = { ...filter }
properties.forEach((prop) => {
console.log('prop', prop)
if (Object.prototype.hasOwnProperty.call(value, prop)) {
const filterValue = value[prop]
if (filterValue?.name) {
valueFilter[prop] = filterValue.name
} else if (Array.isArray(filterValue)) {
valueFilter[prop] = filterValue.join(',')
} else {
valueFilter[prop] = filterValue
}
@ -211,7 +234,7 @@ const ObjectSelect = ({
setInitialized(true)
return
}
if (!initialized) {
if (!initialized && token != null) {
handleFetchObjectsProperties()
setInitialized(true)
}
@ -254,6 +277,7 @@ const ObjectSelect = ({
{...rest}
value={treeSelectValue}
onChange={onTreeSelectChange}
disabled={disabled}
/>
)
}
@ -261,13 +285,15 @@ const ObjectSelect = ({
ObjectSelect.propTypes = {
properties: PropTypes.arrayOf(PropTypes.string).isRequired,
filter: PropTypes.object,
masterFilter: PropTypes.object,
useFilter: PropTypes.bool,
value: PropTypes.any,
onChange: PropTypes.func,
showSearch: PropTypes.bool,
multiple: PropTypes.bool,
treeSelectProps: PropTypes.object,
type: PropTypes.string.isRequired
type: PropTypes.string.isRequired,
disabled: PropTypes.bool
}
export default ObjectSelect