u
This commit is contained in:
@@ -5,19 +5,18 @@ import Chip from '@mui/material/Chip';
|
||||
import Divider from '@mui/material/Divider';
|
||||
import IconButton from '@mui/material/IconButton';
|
||||
import TextField from '@mui/material/TextField';
|
||||
import Tooltip from '@mui/material/Tooltip';
|
||||
import Typography from '@mui/material/Typography';
|
||||
import AddIcon from '@mui/icons-material/Add';
|
||||
import ArrowDownwardIcon from '@mui/icons-material/ArrowDownward';
|
||||
import ArrowUpwardIcon from '@mui/icons-material/ArrowUpward';
|
||||
import CheckIcon from '@mui/icons-material/Check';
|
||||
import CloseIcon from '@mui/icons-material/Close';
|
||||
import ContentCopyIcon from '@mui/icons-material/ContentCopy';
|
||||
import DeleteOutlinedIcon from '@mui/icons-material/DeleteOutlined';
|
||||
import EditOutlinedIcon from '@mui/icons-material/EditOutlined';
|
||||
import LocalPrintshopOutlinedIcon from '@mui/icons-material/LocalPrintshopOutlined';
|
||||
import CheckCircleOutlinedIcon from '@mui/icons-material/CheckCircleOutlined';
|
||||
import HourglassEmptyIcon from '@mui/icons-material/HourglassEmpty';
|
||||
import QRCode from 'qrcode';
|
||||
import { enqueueSnackbar } from 'notistack';
|
||||
import BackendError from '../BackendError';
|
||||
import companyAutomat from '../../automats/companyAutomat';
|
||||
@@ -41,6 +40,80 @@ function formatDateTime(val) {
|
||||
}
|
||||
}
|
||||
|
||||
class AgentQrCode extends PureComponent {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = { dataUrl: null };
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.generateQr();
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps) {
|
||||
if (prevProps.value !== this.props.value || prevProps.size !== this.props.size) {
|
||||
this.generateQr();
|
||||
}
|
||||
}
|
||||
|
||||
async generateQr() {
|
||||
const { value, size = 110 } = this.props;
|
||||
if (!value) {
|
||||
this.setState({ dataUrl: null });
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const dataUrl = await QRCode.toDataURL(value, {
|
||||
width: size,
|
||||
margin: 1,
|
||||
color: {
|
||||
dark: '#000000',
|
||||
light: '#ffffff',
|
||||
},
|
||||
errorCorrectionLevel: 'M',
|
||||
});
|
||||
this.setState({ dataUrl });
|
||||
} catch (err) {
|
||||
console.error('Failed to generate QR code:', err);
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
const { size = 110 } = this.props;
|
||||
const { dataUrl } = this.state;
|
||||
if (!dataUrl) {
|
||||
return (
|
||||
<Box
|
||||
sx={{
|
||||
width: size,
|
||||
height: size,
|
||||
bgcolor: 'action.hover',
|
||||
borderRadius: 1,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<Box
|
||||
component="img"
|
||||
src={dataUrl}
|
||||
alt="Pairing QR Code"
|
||||
sx={{
|
||||
width: size,
|
||||
height: size,
|
||||
borderRadius: 1,
|
||||
border: '1px solid',
|
||||
borderColor: 'divider',
|
||||
bgcolor: '#fff',
|
||||
p: 0.5,
|
||||
display: 'block',
|
||||
flexShrink: 0,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default class PrinterAgentSettingsPanel extends PureComponent {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
@@ -76,7 +149,7 @@ export default class PrinterAgentSettingsPanel extends PureComponent {
|
||||
error: state.printeragentsError ? backendErrorFrom(state.printeragentsError) : null,
|
||||
}));
|
||||
if (companyAutomat.state.printeragentsStatus === 'idle') {
|
||||
void companyAutomat.actions.loadPrinterAgents().catch(() => {});
|
||||
void companyAutomat.actions.loadPrinterAgents().catch(() => { });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -385,7 +458,6 @@ export default class PrinterAgentSettingsPanel extends PureComponent {
|
||||
<Typography variant="subtitle1" fontWeight={600}>
|
||||
{agent.name}
|
||||
</Typography>
|
||||
<Tooltip title="Name bearbeiten">
|
||||
<IconButton
|
||||
size="small"
|
||||
onClick={() => this.handleStartRename(agent)}
|
||||
@@ -394,7 +466,6 @@ export default class PrinterAgentSettingsPanel extends PureComponent {
|
||||
>
|
||||
<EditOutlinedIcon sx={{ fontSize: 16 }} />
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
</Box>
|
||||
)}
|
||||
|
||||
@@ -433,33 +504,47 @@ export default class PrinterAgentSettingsPanel extends PureComponent {
|
||||
</Box>
|
||||
</Box>
|
||||
|
||||
{/* Body: Pairing details or PIN info */}
|
||||
{/* Body: Pairing details with QR code or Paired status info */}
|
||||
<Box
|
||||
sx={{
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'space-between',
|
||||
flexWrap: 'wrap',
|
||||
gap: 2,
|
||||
flexDirection: 'column',
|
||||
gap: 1.5,
|
||||
pt: 0.5,
|
||||
}}
|
||||
>
|
||||
{!isPaired ? (
|
||||
<Box sx={{ display: 'flex', alignItems: 'center', gap: 1.5, flexWrap: 'wrap' }}>
|
||||
<Typography variant="body2" color="text.secondary">
|
||||
(() => {
|
||||
const domain = typeof window !== 'undefined' ? window.location.host : '';
|
||||
const qrPayload = JSON.stringify({
|
||||
domain,
|
||||
pin: String(agent.pairingpin || ''),
|
||||
});
|
||||
return (
|
||||
<Box
|
||||
sx={{
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
gap: 2,
|
||||
flexWrap: 'wrap',
|
||||
bgcolor: 'action.hover',
|
||||
p: 1.5,
|
||||
borderRadius: 1.5,
|
||||
border: '1px solid',
|
||||
borderColor: 'warning.light',
|
||||
}}
|
||||
>
|
||||
<Box sx={{ display: 'inline-flex' }}>
|
||||
<AgentQrCode value={qrPayload} size={110} />
|
||||
</Box>
|
||||
|
||||
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 1, flex: 1, minWidth: 220 }}>
|
||||
<Box sx={{ display: 'flex', alignItems: 'center', gap: 1, flexWrap: 'wrap' }}>
|
||||
<Typography variant="body2" color="text.secondary" sx={{ fontWeight: 500 }}>
|
||||
Kopplungs-PIN:
|
||||
</Typography>
|
||||
<Tooltip title="PIN in die Zwischenablage kopieren">
|
||||
<Chip
|
||||
icon={<ContentCopyIcon sx={{ fontSize: 14 }} />}
|
||||
label={agent.pairingpin || '—'}
|
||||
onClick={() => {
|
||||
if (agent.pairingpin) {
|
||||
navigator.clipboard?.writeText(agent.pairingpin);
|
||||
enqueueSnackbar('PIN in Zwischenablage kopiert.', { variant: 'info' });
|
||||
}
|
||||
}}
|
||||
clickable
|
||||
color="warning"
|
||||
variant="filled"
|
||||
sx={{
|
||||
@@ -470,11 +555,23 @@ export default class PrinterAgentSettingsPanel extends PureComponent {
|
||||
px: 0.5,
|
||||
}}
|
||||
/>
|
||||
</Tooltip>
|
||||
<Typography variant="caption" color="text.secondary">
|
||||
Geben Sie diesen PIN auf dem Drucker-Agent-Gerät ein.
|
||||
</Typography>
|
||||
</Box>
|
||||
|
||||
<Box sx={{ display: 'flex', alignItems: 'center', gap: 1, flexWrap: 'wrap' }}>
|
||||
<Typography variant="body2" color="text.secondary" sx={{ fontWeight: 500 }}>
|
||||
Domain:
|
||||
</Typography>
|
||||
<Chip
|
||||
label={domain}
|
||||
size="small"
|
||||
variant="outlined"
|
||||
sx={{ fontFamily: 'monospace', fontSize: '0.8rem' }}
|
||||
/>
|
||||
</Box>
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
})()
|
||||
) : (
|
||||
<Box sx={{ display: 'flex', alignItems: 'center', gap: 1.5, flexWrap: 'wrap' }}>
|
||||
{agent.clientserial ? (
|
||||
@@ -513,12 +610,11 @@ export default class PrinterAgentSettingsPanel extends PureComponent {
|
||||
</Box>
|
||||
)}
|
||||
|
||||
{/* Sort Order Controls */}
|
||||
<Box sx={{ display: 'flex', alignItems: 'center', gap: 0.5, ml: 'auto' }}>
|
||||
{/* Row with Sort Order Controls */}
|
||||
<Box sx={{ display: 'flex', alignItems: 'center', justifyContent: 'flex-end', gap: 0.5, pt: 0.5 }}>
|
||||
<Typography variant="body2" color="text.secondary">
|
||||
Reihenfolge:
|
||||
</Typography>
|
||||
<Tooltip title="Nach oben verschieben">
|
||||
<span>
|
||||
<IconButton
|
||||
size="small"
|
||||
@@ -529,8 +625,7 @@ export default class PrinterAgentSettingsPanel extends PureComponent {
|
||||
<ArrowUpwardIcon sx={{ fontSize: 16 }} />
|
||||
</IconButton>
|
||||
</span>
|
||||
</Tooltip>
|
||||
<Tooltip title="Nach unten verschieben">
|
||||
|
||||
<span>
|
||||
<IconButton
|
||||
size="small"
|
||||
@@ -541,7 +636,6 @@ export default class PrinterAgentSettingsPanel extends PureComponent {
|
||||
<ArrowDownwardIcon sx={{ fontSize: 16 }} />
|
||||
</IconButton>
|
||||
</span>
|
||||
</Tooltip>
|
||||
<TextField
|
||||
type="number"
|
||||
size="small"
|
||||
|
||||
Reference in New Issue
Block a user