155 lines
4.2 KiB
JavaScript
155 lines
4.2 KiB
JavaScript
// PrinterSelect.js
|
|
import PropTypes from 'prop-types'
|
|
import { TreeSelect, message, Tag } from 'antd'
|
|
import React, { useEffect, useState, useContext } from 'react'
|
|
import axios from 'axios'
|
|
import PrinterState from './PrinterState'
|
|
import { AuthContext } from '../../Auth/AuthContext'
|
|
import config from '../../../config'
|
|
|
|
const PrinterSelect = ({ onChange, disabled, checkable, value = [] }) => {
|
|
const [printersTreeData, setPrintersTreeData] = useState([])
|
|
const [printersData, setPrintersData] = useState([])
|
|
const [loading, setLoading] = useState(true)
|
|
const [messageApi] = message.useMessage()
|
|
const [defaultValue, setDefaultValue] = useState(value)
|
|
|
|
const { authenticated } = useContext(AuthContext)
|
|
|
|
const fetchPrintersTreeData = async () => {
|
|
if (!authenticated) {
|
|
return
|
|
}
|
|
setLoading(true)
|
|
|
|
try {
|
|
const response = await axios.get(`${config.backendUrl}/printers`, {
|
|
headers: {
|
|
Accept: 'application/json'
|
|
},
|
|
withCredentials: true // Important for including cookies
|
|
})
|
|
setLoading(false)
|
|
return response.data
|
|
} catch (error) {
|
|
if (error.response) {
|
|
// For other errors, show a message
|
|
messageApi.error('Error fetching printers data:', error.response.status)
|
|
} else {
|
|
messageApi.error(
|
|
'An unexpected error occurred. Please try again later.'
|
|
)
|
|
}
|
|
}
|
|
}
|
|
|
|
const generatePrinterItems = async () => {
|
|
const printerData = await fetchPrintersTreeData()
|
|
|
|
setPrintersData(printerData)
|
|
|
|
// Create a map to store tags and their printers
|
|
const tagMap = new Map()
|
|
|
|
// Add printers to their respective tag groups
|
|
printerData.forEach((printer) => {
|
|
if (printer.tags && printer.tags.length > 0) {
|
|
printer.tags.forEach((tag) => {
|
|
if (!tagMap.has(tag)) {
|
|
tagMap.set(tag, [])
|
|
}
|
|
tagMap.get(tag).push(printer)
|
|
})
|
|
} else {
|
|
// If no tags, add to "Untagged" group
|
|
if (!tagMap.has('Untagged')) {
|
|
tagMap.set('Untagged', [])
|
|
}
|
|
tagMap.get('Untagged').push(printer)
|
|
}
|
|
})
|
|
|
|
// Convert the map to tree data structure
|
|
Array.from(tagMap.entries()).map(([tag, printers]) => {
|
|
const newNode = {
|
|
title: tag === 'Untagged' ? tag : <Tag color='blue'>{tag}</Tag>,
|
|
value: `tag-${tag}`,
|
|
key: `tag-${tag}`,
|
|
children: printers.map((printer) => ({
|
|
title: (
|
|
<PrinterState
|
|
printer={printer}
|
|
showProgress={false}
|
|
showControls={false}
|
|
/>
|
|
),
|
|
value: printer._id,
|
|
key: printer._id
|
|
}))
|
|
}
|
|
setPrintersTreeData((prev) => {
|
|
const filtered = prev.filter((node) => node.key !== newNode.key)
|
|
return [...filtered, newNode]
|
|
})
|
|
})
|
|
}
|
|
|
|
const handleOnChange = (value, selectedOptions) => {
|
|
if (checkable) {
|
|
// Multiple selection mode
|
|
const newValue = printersData.filter((printer) =>
|
|
value.includes(printer._id)
|
|
)
|
|
setDefaultValue(newValue)
|
|
onChange(newValue, selectedOptions)
|
|
} else {
|
|
// Single selection mode
|
|
const selectedPrinter = printersData.find(
|
|
(printer) => printer._id === value
|
|
)
|
|
setDefaultValue(selectedPrinter ? [selectedPrinter] : [])
|
|
onChange(selectedPrinter, selectedOptions)
|
|
}
|
|
}
|
|
|
|
useEffect(() => {
|
|
if (value) {
|
|
if (Array.isArray(value)) {
|
|
setDefaultValue(value)
|
|
} else {
|
|
setDefaultValue([value])
|
|
}
|
|
}
|
|
}, [value])
|
|
|
|
useEffect(() => {
|
|
generatePrinterItems()
|
|
}, [])
|
|
|
|
return (
|
|
<TreeSelect
|
|
treeData={printersTreeData}
|
|
onChange={handleOnChange}
|
|
loading={loading}
|
|
disabled={disabled}
|
|
treeDefaultExpandAll
|
|
treeCheckable={checkable}
|
|
treeNodeFilterProp='title'
|
|
placeholder='Select printer'
|
|
style={{ width: '100%' }}
|
|
value={
|
|
checkable ? defaultValue.map((item) => item._id) : defaultValue[0]?._id
|
|
}
|
|
/>
|
|
)
|
|
}
|
|
|
|
PrinterSelect.propTypes = {
|
|
onChange: PropTypes.func.isRequired,
|
|
disabled: PropTypes.bool.isRequired,
|
|
checkable: PropTypes.bool,
|
|
value: PropTypes.oneOfType([PropTypes.object, PropTypes.array])
|
|
}
|
|
|
|
export default PrinterSelect
|