diff --git a/src/components/Dashboard/Management/AuditLogs.jsx b/src/components/Dashboard/Management/AuditLogs.jsx
index 3df2571..96a92f2 100644
--- a/src/components/Dashboard/Management/AuditLogs.jsx
+++ b/src/components/Dashboard/Management/AuditLogs.jsx
@@ -24,6 +24,7 @@ import AuditLogIcon from '../../Icons/AuditLogIcon'
import XMarkIcon from '../../Icons/XMarkIcon'
import CheckIcon from '../../Icons/CheckIcon'
import BoolDisplay from '../common/BoolDisplay'
+import StateTag from '../common/StateTag'
const { Text } = Typography
@@ -48,9 +49,7 @@ const formatValue = (value, propertyName) => {
}
if (propertyName === 'state' && typeof value === 'object' && value.type) {
- return (
- {value.type.charAt(0).toUpperCase() + value.type.slice(1)}
- )
+ return
}
// Check if the value is a timestamp (ISO date string)
diff --git a/src/components/Dashboard/common/AuditLogTable.jsx b/src/components/Dashboard/common/AuditLogTable.jsx
index 5a22f06..a486286 100644
--- a/src/components/Dashboard/common/AuditLogTable.jsx
+++ b/src/components/Dashboard/common/AuditLogTable.jsx
@@ -5,6 +5,7 @@ import IdText from './IdText'
import { AuditOutlined, LoadingOutlined } from '@ant-design/icons'
import TimeDisplay from '../common/TimeDisplay'
import BoolDisplay from './BoolDisplay'
+import StateTag from './StateTag'
const { Text } = Typography
@@ -33,9 +34,7 @@ const formatValue = (value, propertyName) => {
}
if (propertyName === 'state' && typeof value === 'object' && value.type) {
- return (
- {value.type.charAt(0).toUpperCase() + value.type.slice(1)}
- )
+ return
}
// Check if the value is a timestamp (ISO date string)
diff --git a/src/components/Dashboard/common/FilamentSelect.jsx b/src/components/Dashboard/common/FilamentSelect.jsx
index 55d15f8..313593d 100644
--- a/src/components/Dashboard/common/FilamentSelect.jsx
+++ b/src/components/Dashboard/common/FilamentSelect.jsx
@@ -28,9 +28,4 @@ FilamentSelect.propTypes = {
useFilter: PropTypes.bool
}
-FilamentSelect.defaultProps = {
- filter: {},
- useFilter: false
-}
-
export default FilamentSelect
diff --git a/src/components/Dashboard/common/JobState.jsx b/src/components/Dashboard/common/JobState.jsx
index 76f28c5..96afec5 100644
--- a/src/components/Dashboard/common/JobState.jsx
+++ b/src/components/Dashboard/common/JobState.jsx
@@ -1,8 +1,9 @@
import PropTypes from 'prop-types'
-import { Badge, Progress, Flex, Typography, Tag, Space } from 'antd'
+import { Progress, Flex, Typography, Space } from 'antd'
import React, { useState, useContext, useEffect } from 'react'
import { SocketContext } from '../context/SocketContext'
import IdText from './IdText'
+import StateTag from './StateTag'
const JobState = ({
job,
@@ -12,13 +13,12 @@ const JobState = ({
showQuantity = true
}) => {
const { socket } = useContext(SocketContext)
- const [badgeStatus, setBadgeStatus] = useState('default')
- const [badgeText, setBadgeText] = useState('Unknown')
const [currentState, setCurrentState] = useState(
job?.state || { type: 'unknown', progress: 0 }
)
const [initialized, setInitialized] = useState(false)
const { Text } = Typography
+
useEffect(() => {
if (socket && !initialized && job?._id) {
setInitialized(true)
@@ -35,38 +35,6 @@ const JobState = ({
}
}, [socket, initialized, job?._id])
- useEffect(() => {
- switch (currentState?.type) {
- case 'draft':
- setBadgeStatus('default')
- setBadgeText('Draft')
- break
- case 'printing':
- setBadgeStatus('processing')
- setBadgeText('Printing')
- break
- case 'complete':
- setBadgeStatus('success')
- setBadgeText('Complete')
- break
- case 'failed':
- setBadgeStatus('error')
- setBadgeText('Failed')
- break
- case 'queued':
- setBadgeStatus('warning')
- setBadgeText('Queued')
- break
- case 'paused':
- setBadgeStatus('warning')
- setBadgeText('Paused')
- break
- default:
- setBadgeStatus('default')
- setBadgeText('Unknown')
- }
- }, [currentState])
-
return (
{showId && (
@@ -75,12 +43,7 @@ const JobState = ({
{showQuantity && ({job.quantity})}
{showStatus && (
-
-
-
- {badgeText}
-
-
+
)}
{showProgress &&
diff --git a/src/components/Dashboard/common/ObjectSelect.jsx b/src/components/Dashboard/common/ObjectSelect.jsx
index 37fa708..9c906c0 100644
--- a/src/components/Dashboard/common/ObjectSelect.jsx
+++ b/src/components/Dashboard/common/ObjectSelect.jsx
@@ -4,8 +4,9 @@ import { TreeSelect, Typography, Flex, Badge } from 'antd'
import axios from 'axios'
import { getTypeMeta } from '../utils/Utils'
import IdText from './IdText'
+import CountryDisplay from './CountryDisplay'
const { Text } = Typography
-
+const { SHOW_CHILD } = TreeSelect
/**
* ObjectSelect - a generic, reusable async TreeSelect for hierarchical object selection.
*
@@ -14,9 +15,10 @@ const { Text } = Typography
* - propertyOrder: array of property names for category levels (required)
* - filter: object for filtering (optional)
* - useFilter: bool (optional)
- * - value: selected value (optional) - can be an object with _id or a simple value
+ * - value: selected value (optional) - can be an object with _id, array of objects, or simple value/array
* - onChange: function (optional)
* - showSearch: bool (optional, default false)
+ * - treeCheckable: bool (optional, default false) - enables multi-select mode with checkboxes
* - treeSelectProps: any other TreeSelect props (optional)
*/
const ObjectSelect = ({
@@ -27,13 +29,14 @@ const ObjectSelect = ({
value,
onChange,
showSearch = false,
+ treeCheckable = false,
treeSelectProps = {},
type = 'unknown',
...rest
}) => {
const [treeData, setTreeData] = useState([])
const [loading, setLoading] = useState(false)
- const [defaultValue, setDefaultValue] = useState(value)
+ const [defaultValue, setDefaultValue] = useState(treeCheckable ? [] : value)
const [searchValue, setSearchValue] = useState('')
const [error, setError] = useState(false)
@@ -102,7 +105,12 @@ const ObjectSelect = ({
const renderTitle = useCallback(
(item, isLeaf) => {
if (!isLeaf) {
- // For category nodes, just show the value
+ // For category nodes, check if it's a country property
+ const currentProperty = propertyOrder[item.propertyId]
+ if (currentProperty === 'country' && item.value) {
+ return
+ }
+ // For other category nodes, just show the value
return {item[propertyOrder[item.propertyId]] || item.value}
}
// For leaf nodes, show icon, name, and id
@@ -129,8 +137,9 @@ const ObjectSelect = ({
let currentPId = 0
// Build category nodes for each property level and load all available options
- for (let i = 0; i < propertyOrder.length - 1; i++) {
+ for (let i = 0; i < propertyOrder.length; i++) {
const propertyName = propertyOrder[i]
+ console.log('propname', propertyName)
let propertyValue
// Handle nested property access (e.g., 'filament.diameter')
@@ -372,9 +381,25 @@ const ObjectSelect = ({
// OnChange handler
const handleOnChange = (val, selectedOptions) => {
if (onChange) {
- // Find the raw object for the selected value
- const node = treeData.find((n) => n.value === val)
- onChange(node ? node.raw : val, selectedOptions)
+ if (treeCheckable) {
+ // Handle multiple selections with checkboxes
+ const selectedObjects = []
+ if (Array.isArray(val)) {
+ val.forEach((selectedValue) => {
+ const node = treeData.find((n) => n.value === selectedValue)
+ if (node) {
+ selectedObjects.push(node.raw)
+ } else {
+ selectedObjects.push(selectedValue)
+ }
+ })
+ }
+ onChange(selectedObjects, selectedOptions)
+ } else {
+ // Handle single selection
+ const node = treeData.find((n) => n.value === val)
+ onChange(node ? node.raw : val, selectedOptions)
+ }
}
console.log('val', val)
setDefaultValue(val)
@@ -388,29 +413,56 @@ const ObjectSelect = ({
// Keep defaultValue in sync and handle object values
useEffect(() => {
- if (value?._id) {
- setDefaultValue(value._id)
- }
+ if (treeCheckable) {
+ // Handle array of values for multi-select
+ if (Array.isArray(value)) {
+ const valueIds = value.map((v) => v._id || v.id || v)
+ setDefaultValue(valueIds)
- // Check if value is an object with _id (default object case)
- if (value && typeof value === 'object' && value._id) {
- // If we already have this object loaded, don't fetch again
- const existingNode = treeData.find((node) => node.value === value._id)
- if (!existingNode) {
- fetchObjectById(value._id).then((object) => {
- if (object) {
- buildTreePathForObject(object)
+ // Load tree paths for any objects that aren't already loaded
+ value.forEach((item) => {
+ if (item && typeof item === 'object' && item._id) {
+ const existingNode = treeData.find(
+ (node) => node.value === item._id
+ )
+ if (!existingNode) {
+ fetchObjectById(item._id).then((object) => {
+ if (object) {
+ buildTreePathForObject(object)
+ }
+ })
+ }
}
})
+ } else {
+ setDefaultValue([])
+ }
+ } else {
+ // Handle single value
+ if (value?._id) {
+ setDefaultValue(value._id)
+ }
+
+ // Check if value is an object with _id (default object case)
+ if (value && typeof value === 'object' && value._id) {
+ // If we already have this object loaded, don't fetch again
+ const existingNode = treeData.find((node) => node.value === value._id)
+ if (!existingNode) {
+ fetchObjectById(value._id).then((object) => {
+ if (object) {
+ buildTreePathForObject(object)
+ }
+ })
+ }
}
}
- }, [value, treeData, fetchObjectById, buildTreePathForObject])
+ }, [value, treeData, fetchObjectById, buildTreePathForObject, treeCheckable])
// Initial load
useEffect(() => {
if (treeData.length === 0 && !error && !loading) {
// If we have a default object value, don't load the regular tree
- if (value && typeof value === 'object' && value._id) {
+ if (!treeCheckable && value && typeof value === 'object' && value._id) {
return
}
@@ -429,7 +481,8 @@ const ObjectSelect = ({
handleTreeLoad,
error,
loading,
- value
+ value,
+ treeCheckable
])
return error ? (
@@ -455,6 +508,8 @@ const ObjectSelect = ({
value={defaultValue}
showSearch={showSearch}
onSearch={showSearch ? handleSearch : undefined}
+ treeCheckable={treeCheckable}
+ showCheckedStrategy={treeCheckable ? SHOW_CHILD : undefined}
{...treeSelectProps}
{...rest}
/>
@@ -469,6 +524,7 @@ ObjectSelect.propTypes = {
value: PropTypes.any,
onChange: PropTypes.func,
showSearch: PropTypes.bool,
+ treeCheckable: PropTypes.bool,
treeSelectProps: PropTypes.object,
type: PropTypes.string.isRequired
}
diff --git a/src/components/Dashboard/common/PrinterSelect.jsx b/src/components/Dashboard/common/PrinterSelect.jsx
index 11710f9..373cbee 100644
--- a/src/components/Dashboard/common/PrinterSelect.jsx
+++ b/src/components/Dashboard/common/PrinterSelect.jsx
@@ -1,36 +1,18 @@
// PrinterSelect.js
import React from 'react'
import PropTypes from 'prop-types'
-import { Tag } from 'antd'
import config from '../../../config'
import ObjectSelect from './ObjectSelect'
-import PrinterState from './PrinterState'
const PrinterSelect = ({ onChange, disabled }) => {
- // getTitle: if isLeaf, render PrinterState, else render Tag or 'Untagged'
- const getTitle = (item, isLeaf) =>
- isLeaf ? (
-
- ) : item === 'Untagged' ? (
- 'Untagged'
- ) : (
- {item}
- )
-
- // getValue/getKey: for leaf, use _id; for tag, use tag string
- const getValue = (item, isLeaf) => (isLeaf ? item._id : item)
- const getKey = (item, isLeaf) => (isLeaf ? item._id : item)
-
return (
)
}
diff --git a/src/components/Dashboard/common/PrinterState.jsx b/src/components/Dashboard/common/PrinterState.jsx
index e4f05e9..df93d49 100644
--- a/src/components/Dashboard/common/PrinterState.jsx
+++ b/src/components/Dashboard/common/PrinterState.jsx
@@ -1,20 +1,12 @@
// PrinterSelect.js
import PropTypes from 'prop-types'
-import {
- Badge,
- Progress,
- Flex,
- Space,
- Tag,
- Typography,
- Button,
- Tooltip
-} from 'antd'
+import { Progress, Flex, Space, Typography, Button, Tooltip } from 'antd'
import React, { useState, useContext, useEffect } from 'react'
import { SocketContext } from '../context/SocketContext'
import { CaretLeftOutlined } from '@ant-design/icons'
import XMarkIcon from '../../Icons/XMarkIcon'
import PauseIcon from '../../Icons/PauseIcon'
+import StateTag from './StateTag'
const PrinterState = ({
printer,
@@ -24,8 +16,6 @@ const PrinterState = ({
showControls = true
}) => {
const { socket } = useContext(SocketContext)
- const [badgeStatus, setBadgeStatus] = useState('unknown')
- const [badgeText, setBadgeText] = useState('Unknown')
const [currentState, setCurrentState] = useState(
printer?.state || {
type: 'unknown',
@@ -51,81 +41,12 @@ const PrinterState = ({
}
}, [socket, initialized, printer?.id])
- useEffect(() => {
- switch (currentState.type) {
- case 'online':
- setBadgeStatus('success')
- setBadgeText('Online')
- break
- case 'standby':
- setBadgeStatus('success')
- setBadgeText('Standby')
- break
- case 'complete':
- setBadgeStatus('success')
- setBadgeText('Complete')
- break
- case 'offline':
- setBadgeStatus('default')
- setBadgeText('Offline')
- break
- case 'shutdown':
- setBadgeStatus('default')
- setBadgeText('Shutdown')
- break
- case 'initializing':
- setBadgeStatus('warning')
- setBadgeText('Initializing')
- break
- case 'printing':
- setBadgeStatus('processing')
- setBadgeText('Printing')
- break
- case 'paused':
- setBadgeStatus('warning')
- setBadgeText('Paused')
- break
- case 'cancelled':
- setBadgeStatus('warning')
- setBadgeText('Cancelled')
- break
- case 'loading':
- setBadgeStatus('processing')
- setBadgeText('Uploading')
- break
- case 'processing':
- setBadgeStatus('processing')
- setBadgeText('Processing')
- break
- case 'ready':
- setBadgeStatus('success')
- setBadgeText('Ready')
- break
- case 'error':
- setBadgeStatus('error')
- setBadgeText('Error')
- break
- case 'startup':
- setBadgeStatus('warning')
- setBadgeText('Startup')
- break
- default:
- setBadgeStatus('default')
- setBadgeText(currentState.type)
- }
- }, [currentState])
-
return (
{showPrinterName && {printer.name}}
{showStatus && (
-
-
-
- {badgeText}
-
-
+
)}
{showProgress &&
diff --git a/src/components/Dashboard/common/StateTag.jsx b/src/components/Dashboard/common/StateTag.jsx
new file mode 100644
index 0000000..e41c49a
--- /dev/null
+++ b/src/components/Dashboard/common/StateTag.jsx
@@ -0,0 +1,103 @@
+import PropTypes from 'prop-types'
+import { Badge, Flex, Tag } from 'antd'
+import React, { useMemo } from 'react'
+
+const StateTag = ({ state, showBadge = true, style = {} }) => {
+ const { badgeStatus, badgeText } = useMemo(() => {
+ let status = 'default'
+ let text = 'Unknown'
+
+ switch (state) {
+ case 'online':
+ status = 'success'
+ text = 'Online'
+ break
+ case 'standby':
+ status = 'success'
+ text = 'Standby'
+ break
+ case 'complete':
+ status = 'success'
+ text = 'Complete'
+ break
+ case 'offline':
+ status = 'default'
+ text = 'Offline'
+ break
+ case 'shutdown':
+ status = 'default'
+ text = 'Shutdown'
+ break
+ case 'initializing':
+ status = 'warning'
+ text = 'Initializing'
+ break
+ case 'printing':
+ status = 'processing'
+ text = 'Printing'
+ break
+ case 'paused':
+ status = 'warning'
+ text = 'Paused'
+ break
+ case 'cancelled':
+ status = 'error'
+ text = 'Cancelled'
+ break
+ case 'loading':
+ status = 'processing'
+ text = 'Uploading'
+ break
+ case 'processing':
+ status = 'processing'
+ text = 'Processing'
+ break
+ case 'ready':
+ status = 'success'
+ text = 'Ready'
+ break
+ case 'error':
+ status = 'error'
+ text = 'Error'
+ break
+ case 'startup':
+ status = 'warning'
+ text = 'Startup'
+ break
+ case 'draft':
+ status = 'default'
+ text = 'Draft'
+ break
+ case 'failed':
+ status = 'error'
+ text = 'Failed'
+ break
+ case 'queued':
+ status = 'warning'
+ text = 'Queued'
+ break
+ default:
+ status = 'default'
+ text = state || 'Unknown'
+ }
+
+ return { badgeStatus: status, badgeText: text }
+ }, [state])
+
+ return (
+
+
+ {showBadge && }
+ {badgeText}
+
+
+ )
+}
+
+StateTag.propTypes = {
+ state: PropTypes.string,
+ showBadge: PropTypes.bool,
+ style: PropTypes.object
+}
+
+export default StateTag
diff --git a/src/components/Dashboard/common/SubJobState.jsx b/src/components/Dashboard/common/SubJobState.jsx
index ca0f0a6..ea90db0 100644
--- a/src/components/Dashboard/common/SubJobState.jsx
+++ b/src/components/Dashboard/common/SubJobState.jsx
@@ -1,9 +1,10 @@
import PropTypes from 'prop-types'
-import { Badge, Progress, Flex, Button, Space, Tag, Tooltip } from 'antd' // eslint-disable-line
+import { Progress, Flex, Button, Space, Tooltip } from 'antd' // eslint-disable-line
import { CaretLeftOutlined } from '@ant-design/icons' // eslint-disable-line
import React, { useState, useContext, useEffect } from 'react'
import { SocketContext } from '../context/SocketContext'
import IdText from './IdText'
+import StateTag from './StateTag'
import XMarkIcon from '../../Icons/XMarkIcon'
import PauseIcon from '../../Icons/PauseIcon'
import BinIcon from '../../Icons/BinIcon'
@@ -16,8 +17,6 @@ const SubJobState = ({
showControls = true //eslint-disable-line
}) => {
const { socket } = useContext(SocketContext)
- const [badgeStatus, setBadgeStatus] = useState('unknown')
- const [badgeText, setBadgeText] = useState('Unknown')
const [currentState, setCurrentState] = useState(
subJob?.state || {
type: 'unknown',
@@ -45,42 +44,6 @@ const SubJobState = ({
}
}, [socket, initialized, subJob?._id])
- useEffect(() => {
- switch (currentState.type) {
- case 'draft':
- setBadgeStatus('default')
- setBadgeText('Draft')
- break
- case 'printing':
- setBadgeStatus('processing')
- setBadgeText('Printing')
- break
- case 'complete':
- setBadgeStatus('success')
- setBadgeText('Complete')
- break
- case 'failed':
- setBadgeStatus('error')
- setBadgeText('Failed')
- break
- case 'queued':
- setBadgeStatus('warning')
- setBadgeText('Queued')
- break
- case 'paused':
- setBadgeStatus('warning')
- setBadgeText('Paused')
- break
- case 'cancelled':
- setBadgeStatus('error')
- setBadgeText('Cancelled')
- break
- default:
- setBadgeStatus('default')
- setBadgeText('Unknown')
- }
- }, [currentState])
-
return (
{showId && (
@@ -88,12 +51,7 @@ const SubJobState = ({
)}
{showStatus && (
-
-
-
- {badgeText}
-
-
+
)}
{showProgress &&
diff --git a/src/components/Dashboard/common/VendorSelect.jsx b/src/components/Dashboard/common/VendorSelect.jsx
index 424b442..9e79388 100644
--- a/src/components/Dashboard/common/VendorSelect.jsx
+++ b/src/components/Dashboard/common/VendorSelect.jsx
@@ -1,188 +1,30 @@
-import { TreeSelect, Space } from 'antd'
-import React, { useEffect, useState } from 'react'
+import React from 'react'
import PropTypes from 'prop-types'
-import axios from 'axios'
-import CountryDisplay from './CountryDisplay'
-import VendorIcon from '../../Icons/VendorIcon'
import config from '../../../config'
+import ObjectSelect from './ObjectSelect'
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(`${config.backendUrl}/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: (
-
-
- {vendor.name}
-
- ),
- 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: ,
- 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(() => {
- console.log('value', value)
- if (value?.name) {
- setDefaultValue(value.name)
- }
- }, [value])
-
return (
-
)
}
VendorSelect.propTypes = {
onChange: PropTypes.func,
+ value: PropTypes.object,
filter: PropTypes.object,
- useFilter: PropTypes.bool,
- value: PropTypes.object
+ useFilter: PropTypes.bool
}
export default VendorSelect