From e423f32493f8961a55e91474954169af60053219 Mon Sep 17 00:00:00 2001 From: Tom Butcher Date: Mon, 18 Aug 2025 01:02:27 +0100 Subject: [PATCH] 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. --- .../Dashboard/common/ObjectSelect.jsx | 44 +++++++++++++++---- 1 file changed, 35 insertions(+), 9 deletions(-) diff --git a/src/components/Dashboard/common/ObjectSelect.jsx b/src/components/Dashboard/common/ObjectSelect.jsx index 404edbe..7d2d7c3 100644 --- a/src/components/Dashboard/common/ObjectSelect.jsx +++ b/src/components/Dashboard/common/ObjectSelect.jsx @@ -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 }) - setObjectPropertiesTree((prev) => merge({}, prev, data)) + 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