// FilamentSelect.js import { TreeSelect, Badge } from 'antd' import React, { useEffect, useState, useCallback } from 'react' import PropTypes from 'prop-types' import axios from 'axios' import config from '../../../config' const propertyOrder = ['diameter', 'type', 'vendor.name'] const FilamentSelect = ({ onChange, filter, useFilter, value }) => { const [filamentsTreeData, setFilamentsTreeData] = useState([]) const [filamentsData, setFilamentsData] = useState([]) const [loading, setLoading] = useState(false) const [defaultValue, setDefaultValue] = useState(value) const fetchFilamentsData = async (property, filter) => { setLoading(true) try { const response = await axios.get(`${config.backendUrl}/filaments`, { params: { ...filter, property }, headers: { Accept: 'application/json' }, withCredentials: true }) setLoading(false) return response.data //setPagination({ ...pagination, total: response.data.totalItems }); // Update total count } catch (err) { console.error(err) } } function getByPath(obj, path) { return path.split('.').reduce((acc, part) => acc && acc[part], obj) } const getFilter = useCallback( (node) => { var filter = {} var currentId = node.id while (currentId != 0) { const currentNode = filamentsTreeData.filter( (treeData) => treeData['id'] === currentId )[0] filter[propertyOrder[currentNode.propertyId]] = currentNode.value currentId = currentNode.pId } return filter }, [filamentsTreeData] ) const generateFilamentTreeNodes = useCallback( async (node = null, filter = null) => { if (!node) { return } if (filter === null) { filter = getFilter(node) } const filamentData = await fetchFilamentsData(null, filter) setFilamentsData(filamentData) for (var i = 0; i < filamentData.length; i++) { const filament = filamentData[i] const newNode = { id: filament._id, pId: node.id, value: filament._id, key: filament._id, title: , isLeaf: true } setFilamentsTreeData((prev) => { const filtered = prev.filter((node) => node.id !== newNode.id) return [...filtered, newNode] }) } }, [filamentsTreeData, getFilter] ) const generateFilamentCategoryTreeNodes = useCallback( async (node = null) => { var filter = {} var propertyId = 0 if (!node) { node = {} node.id = 0 } else { filter = getFilter(node) propertyId = node.propertyId + 1 } const propertyName = propertyOrder[propertyId] const propertyData = await fetchFilamentsData(propertyName, filter) for (var i = 0; i < propertyData.length; i++) { const property = getByPath(propertyData[i], propertyName) const newNode = { id: property, pId: node.id, value: property, key: property, propertyId: propertyId, title: property, isLeaf: false, selectable: false } setFilamentsTreeData((prev) => { if (prev.some((node) => node.id === newNode.id)) { return prev // already added } return [...prev, newNode] }) } }, [getFilter] ) const handleFilamentsTreeLoad = useCallback( async (node) => { if (node) { if (node.propertyId !== propertyOrder.length - 1) { await generateFilamentCategoryTreeNodes(node) } else { await generateFilamentTreeNodes(node) // End of properties } } else { await generateFilamentCategoryTreeNodes(null) // First property } }, [generateFilamentTreeNodes, generateFilamentCategoryTreeNodes] ) const handleOnChange = (value, selectedOptions) => { console.log('Handle onchange') const filamentObject = filamentsData.filter( (filament) => filament._id == value )[0] onChange(filamentObject, selectedOptions) } useEffect(() => { if (value?._id != null) { console.log('Setting default value...', value) setDefaultValue(value) } }, [value]) useEffect(() => { console.log('Use Filter', useFilter) if (defaultValue != undefined) { const newNode = { id: defaultValue._id, pId: 0, value: defaultValue._id, key: defaultValue._id, title: , isLeaf: true } console.log('setting new node') setFilamentsTreeData([newNode]) } else { setFilamentsTreeData([]) } if (useFilter === true) { generateFilamentTreeNodes({ id: 0 }, filter) } else { handleFilamentsTreeLoad(null) } }, [useFilter, defaultValue, filter]) return ( ) } FilamentSelect.propTypes = { onChange: PropTypes.func.isRequired, value: PropTypes.object, filter: PropTypes.object, useFilter: PropTypes.bool } FilamentSelect.defaultProps = { filter: {}, useFilter: false } export default FilamentSelect