187 lines
4.4 KiB
JavaScript
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
|