// 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