187 lines
4.4 KiB
JavaScript

import { TreeSelect, Space } from 'antd'
import React, { useEffect, useState } from 'react'
import PropTypes from 'prop-types'
import axios from 'axios'
import CountryDisplay from './CountryDisplay'
import VendorIcon from '../../Icons/VendorIcon'
const propertyOrder = ['country']
const VendorSelect = ({ onChange, filter = {}, useFilter = false, value }) => {
const [vendorsTreeData, setVendorsTreeData] = useState([])
const [loading, setLoading] = useState(true)
const [defaultValue, setDefaultValue] = useState(null)
const fetchVendorsData = async (property, filter) => {
setLoading(true)
try {
const response = await axios.get('http://localhost:8080/vendors', {
params: {
...filter,
property
},
headers: {
Accept: 'application/json'
},
withCredentials: true
})
setLoading(false)
return response.data
} catch (err) {
console.error(err)
}
}
const getFilter = (node) => {
var filter = {}
var currentId = node.id
while (currentId != 0) {
const currentNode = vendorsTreeData.filter(
(treeData) => treeData['id'] === currentId
)[0]
filter[propertyOrder[currentNode.propertyId]] =
currentNode.value.split('-')[0]
currentId = currentNode.pId
}
return filter
}
const generateVendorTreeNodes = async (node = null, filter = null) => {
if (!node) {
return
}
if (filter === null) {
filter = getFilter(node)
}
const vendorData = await fetchVendorsData(null, filter)
let newNodeList = []
for (const vendor of vendorData) {
const random = Math.random().toString(36).substring(2, 6)
const newNode = {
id: random,
pId: node.id,
value: vendor._id,
vendor: vendor,
key: vendor._id,
title: (
<Space>
<VendorIcon />
{vendor.name}
</Space>
),
isLeaf: true
}
newNodeList.push(newNode)
}
setVendorsTreeData(vendorsTreeData.concat(newNodeList))
}
const generateVendorCategoryTreeNodes = 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 fetchVendorsData(propertyName, filter)
const newNodeList = []
for (const item of propertyData) {
const property = item[propertyName]
const random = Math.random().toString(36).substring(2, 6)
const newNode = {
id: random,
pId: node.id,
value: property + '-' + random,
key: property + '-' + random,
propertyId: propertyId,
title: <CountryDisplay countryCode={property} />,
isLeaf: false,
selectable: false
}
newNodeList.push(newNode)
}
setVendorsTreeData(vendorsTreeData.concat(newNodeList))
}
const handleVendorsTreeLoad = async (node) => {
if (node) {
if (node.propertyId !== propertyOrder.length - 1) {
await generateVendorCategoryTreeNodes(node)
} else {
await generateVendorTreeNodes(node) // End of properties
}
} else {
await generateVendorCategoryTreeNodes(null) // First property
}
}
const handleOnChange = (value, selectedOptions) => {
const vendorObject = vendorsTreeData.find(
(node) => node.value === value
)?.vendor
onChange(vendorObject, selectedOptions)
}
useEffect(() => {
setVendorsTreeData([])
}, [])
useEffect(() => {
if (vendorsTreeData.length === 0) {
if (useFilter === true) {
generateVendorTreeNodes({ id: 0 }, filter)
} else {
handleVendorsTreeLoad(null)
}
}
}, [vendorsTreeData])
useEffect(() => {
if (value?.name) {
setDefaultValue(value.name)
}
}, [value])
return (
<TreeSelect
treeDataSimpleMode
loadData={handleVendorsTreeLoad}
treeData={vendorsTreeData}
onChange={handleOnChange}
loading={loading}
placeholder='Select a vendor'
style={{ width: '100%' }}
value={defaultValue}
/>
)
}
VendorSelect.propTypes = {
onChange: PropTypes.func,
filter: PropTypes.object,
useFilter: PropTypes.bool,
value: PropTypes.object
}
export default VendorSelect