u
This commit is contained in:
@@ -2,6 +2,67 @@ import js from '@eslint/js';
|
||||
import globals from 'globals';
|
||||
import reactHooks from 'eslint-plugin-react-hooks';
|
||||
|
||||
const banMuiTooltipRule = {
|
||||
meta: {
|
||||
type: 'problem',
|
||||
docs: {
|
||||
description: 'Ban MUI Tooltip component',
|
||||
},
|
||||
messages: {
|
||||
badDesign: '<Tooltip> is bad design',
|
||||
},
|
||||
},
|
||||
create(context) {
|
||||
const muiTooltipIdentifiers = new Set();
|
||||
|
||||
return {
|
||||
ImportDeclaration(node) {
|
||||
if (node.source.value === '@mui/material/Tooltip') {
|
||||
context.report({
|
||||
node,
|
||||
messageId: 'badDesign',
|
||||
});
|
||||
for (const specifier of node.specifiers) {
|
||||
if (specifier.local?.name) {
|
||||
muiTooltipIdentifiers.add(specifier.local.name);
|
||||
}
|
||||
}
|
||||
} else if (node.source.value === '@mui/material') {
|
||||
for (const specifier of node.specifiers) {
|
||||
if (
|
||||
specifier.type === 'ImportSpecifier' &&
|
||||
specifier.imported?.name === 'Tooltip'
|
||||
) {
|
||||
context.report({
|
||||
node: specifier,
|
||||
messageId: 'badDesign',
|
||||
});
|
||||
if (specifier.local?.name) {
|
||||
muiTooltipIdentifiers.add(specifier.local.name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
JSXOpeningElement(node) {
|
||||
let tagName = '';
|
||||
if (node.name.type === 'JSXIdentifier') {
|
||||
tagName = node.name.name;
|
||||
} else if (node.name.type === 'JSXMemberExpression') {
|
||||
tagName = node.name.property.name;
|
||||
}
|
||||
|
||||
if (muiTooltipIdentifiers.has(tagName) || tagName === 'Tooltip') {
|
||||
context.report({
|
||||
node,
|
||||
messageId: 'badDesign',
|
||||
});
|
||||
}
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
|
||||
export default [
|
||||
{
|
||||
ignores: [
|
||||
@@ -32,10 +93,16 @@ export default [
|
||||
},
|
||||
plugins: {
|
||||
'react-hooks': reactHooks,
|
||||
react: {
|
||||
rules: {
|
||||
'no-mui-tooltip': banMuiTooltipRule,
|
||||
},
|
||||
},
|
||||
},
|
||||
rules: {
|
||||
'react-hooks/rules-of-hooks': 'error',
|
||||
'react-hooks/exhaustive-deps': 'warn',
|
||||
'react/no-mui-tooltip': 'error',
|
||||
'no-unused-vars': [
|
||||
'warn',
|
||||
{
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
"dev:pwa:https": "VITE_HTTPS=1 node scripts/dev.mjs",
|
||||
"cert": "./scripts/generate-cert.sh",
|
||||
"build": "vite build",
|
||||
"lint": "eslint .",
|
||||
"preview": "vite preview",
|
||||
"preview:https": "VITE_HTTPS=1 vite preview",
|
||||
"rig:collect": "node test/collect.mjs",
|
||||
|
||||
@@ -41,16 +41,19 @@ export const agentprinter = {
|
||||
|
||||
/**
|
||||
* PUT /api/agentprinter/order
|
||||
* Body: { printeragentId: number, agentprinterIds: number[] }
|
||||
* Body: { printeragentId?: number, agentprinterIds: number[] }
|
||||
* → { agentprinterIds: number[] }
|
||||
*/
|
||||
order({ printeragentId, agentprinterIds }) {
|
||||
const body = {
|
||||
agentprinterIds: Array.isArray(agentprinterIds) ? agentprinterIds.map(Number) : [],
|
||||
};
|
||||
if (printeragentId != null) {
|
||||
body.printeragentId = Number(printeragentId);
|
||||
}
|
||||
return http('/api/agentprinter/order', {
|
||||
method: 'PUT',
|
||||
body: {
|
||||
printeragentId: Number(printeragentId),
|
||||
agentprinterIds: Array.isArray(agentprinterIds) ? agentprinterIds.map(Number) : [],
|
||||
},
|
||||
body,
|
||||
});
|
||||
},
|
||||
|
||||
|
||||
@@ -7,7 +7,6 @@ import FormControlLabel from '@mui/material/FormControlLabel';
|
||||
import IconButton from '@mui/material/IconButton';
|
||||
import Switch from '@mui/material/Switch';
|
||||
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';
|
||||
@@ -440,21 +439,17 @@ export default class PrinterAgentSettingsPanel extends PureComponent {
|
||||
|
||||
async handleMovePrinter(printer, direction) {
|
||||
const { agentprinters } = this.state;
|
||||
const printersForAgent = agentprinters.filter(
|
||||
(p) => p.printeragentId === printer.printeragentId,
|
||||
);
|
||||
const currentIndex = printersForAgent.findIndex((p) => p.id === printer.id);
|
||||
const currentIndex = agentprinters.findIndex((p) => p.id === printer.id);
|
||||
if (currentIndex === -1) return;
|
||||
const targetIndex = direction === 'up' ? currentIndex - 1 : currentIndex + 1;
|
||||
if (targetIndex < 0 || targetIndex >= printersForAgent.length) return;
|
||||
if (targetIndex < 0 || targetIndex >= agentprinters.length) return;
|
||||
|
||||
const reordered = [...printersForAgent];
|
||||
const reordered = [...agentprinters];
|
||||
const [moved] = reordered.splice(currentIndex, 1);
|
||||
reordered.splice(targetIndex, 0, moved);
|
||||
|
||||
try {
|
||||
await companyAutomat.actions.reorderAgentPrinters({
|
||||
printeragentId: printer.printeragentId,
|
||||
agentprinterIds: reordered.map((p) => p.id),
|
||||
});
|
||||
} catch (err) {
|
||||
@@ -463,6 +458,11 @@ export default class PrinterAgentSettingsPanel extends PureComponent {
|
||||
}
|
||||
|
||||
async handleDeletePrinter(printer) {
|
||||
const isOnline = Boolean(printer?.online);
|
||||
if (isOnline) {
|
||||
enqueueSnackbar('Online-Drucker können nicht entfernt werden.', { variant: 'warning' });
|
||||
return;
|
||||
}
|
||||
const label = printer.model || printer.serial || `#${printer.id}`;
|
||||
if (!window.confirm(`Möchten Sie den Drucker „${label}“ wirklich entfernen?`)) {
|
||||
return;
|
||||
@@ -521,6 +521,7 @@ export default class PrinterAgentSettingsPanel extends PureComponent {
|
||||
for (const lp of livePrinters) {
|
||||
if (lp.serial) livePrintersBySerial.set(lp.serial, lp);
|
||||
}
|
||||
const agentMap = new Map(printeragents.map((a) => [a.id, a]));
|
||||
|
||||
return (
|
||||
<Box sx={{ p: 3, maxWidth: 900, mx: 'auto' }}>
|
||||
@@ -528,18 +529,13 @@ export default class PrinterAgentSettingsPanel extends PureComponent {
|
||||
<Typography variant="h6" fontWeight={600} gutterBottom>
|
||||
Drucker-Agenten
|
||||
</Typography>
|
||||
<Typography variant="body2" color="text.secondary">
|
||||
Verwalten Sie externe Drucker-Agenten und die daran angeschlossenen Drucker. Nach
|
||||
Erstellung eines Agenten geben Sie die 6-stellige PIN auf dem Gerät ein oder scannen
|
||||
Sie den QR-Code, um die Kopplung abzuschließen.
|
||||
</Typography>
|
||||
</Box>
|
||||
|
||||
{/* Add new agent row */}
|
||||
<Box sx={{ display: 'flex', gap: 1.5, mb: 3, alignItems: 'center' }}>
|
||||
<TextField
|
||||
size="small"
|
||||
placeholder="Neuer Drucker-Agent Name (z.B. Bar, Küche)"
|
||||
placeholder="Agent Name (z.B. Bar, Küche)"
|
||||
value={newAgentName}
|
||||
onChange={(e) => this.setState({ newAgentName: e.target.value })}
|
||||
onKeyDown={(e) => {
|
||||
@@ -595,10 +591,6 @@ export default class PrinterAgentSettingsPanel extends PureComponent {
|
||||
const lastseenText = formatDateTime(agent.lastseenAt) ?? 'Nie';
|
||||
const updatedText = formatDateTime(agent.updatedAt) ?? '—';
|
||||
|
||||
const printersForAgent = agentprinters.filter(
|
||||
(p) => p.printeragentId === agent.id,
|
||||
);
|
||||
|
||||
return (
|
||||
<Box
|
||||
key={agent.id}
|
||||
@@ -727,7 +719,6 @@ export default class PrinterAgentSettingsPanel extends PureComponent {
|
||||
|
||||
{/* Agent version */}
|
||||
{agent.agentversion ? (
|
||||
<Tooltip title="Agent Software-Version">
|
||||
<Chip
|
||||
label={`v${agent.agentversion}`}
|
||||
size="small"
|
||||
@@ -735,7 +726,6 @@ export default class PrinterAgentSettingsPanel extends PureComponent {
|
||||
color="info"
|
||||
sx={{ fontFamily: 'monospace', fontWeight: 600, fontSize: '0.75rem' }}
|
||||
/>
|
||||
</Tooltip>
|
||||
) : null}
|
||||
</Box>
|
||||
|
||||
@@ -808,18 +798,15 @@ export default class PrinterAgentSettingsPanel extends PureComponent {
|
||||
borderColor: 'warning.light',
|
||||
}}
|
||||
>
|
||||
<Tooltip title="QR-Code zum Koppeln mit dem Drucker-Agenten">
|
||||
<Box sx={{ display: 'inline-flex' }}>
|
||||
<AgentQrCode value={qrPayload} size={110} />
|
||||
</Box>
|
||||
</Tooltip>
|
||||
|
||||
<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 || '—'}
|
||||
@@ -840,7 +827,6 @@ export default class PrinterAgentSettingsPanel extends PureComponent {
|
||||
px: 0.5,
|
||||
}}
|
||||
/>
|
||||
</Tooltip>
|
||||
</Box>
|
||||
|
||||
<Box sx={{ display: 'flex', alignItems: 'center', gap: 1, flexWrap: 'wrap' }}>
|
||||
@@ -853,7 +839,6 @@ export default class PrinterAgentSettingsPanel extends PureComponent {
|
||||
variant="outlined"
|
||||
sx={{ fontFamily: 'monospace', fontSize: '0.8rem' }}
|
||||
/>
|
||||
<Tooltip title="QR-Daten (JSON) kopieren">
|
||||
<IconButton
|
||||
size="small"
|
||||
onClick={() => {
|
||||
@@ -864,7 +849,6 @@ export default class PrinterAgentSettingsPanel extends PureComponent {
|
||||
>
|
||||
<ContentCopyIcon sx={{ fontSize: 14 }} />
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
</Box>
|
||||
|
||||
<Typography variant="caption" color="text.secondary">
|
||||
@@ -874,170 +858,7 @@ export default class PrinterAgentSettingsPanel extends PureComponent {
|
||||
</Box>
|
||||
);
|
||||
})()
|
||||
) : (
|
||||
/* Discovered printers section */
|
||||
<Box sx={{ p: 1.5, borderRadius: 1.5, bgcolor: 'action.hover' }}>
|
||||
<Box sx={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', mb: 1 }}>
|
||||
<Typography variant="subtitle2" fontWeight={600} color="text.secondary">
|
||||
Erkannte Drucker ({printersForAgent.length})
|
||||
</Typography>
|
||||
</Box>
|
||||
{printersForAgent.length === 0 ? (
|
||||
<Typography
|
||||
variant="body2"
|
||||
color="text.secondary"
|
||||
sx={{ fontStyle: 'italic', py: 0.5 }}
|
||||
>
|
||||
Keine Drucker erkannt. Schließen Sie einen Drucker per USB an den Agenten an.
|
||||
</Typography>
|
||||
) : (
|
||||
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 1 }}>
|
||||
{printersForAgent.map((p, pIdx) => {
|
||||
const pEnabled = p.enabled !== false;
|
||||
const live =
|
||||
(p.serial ? livePrintersBySerial.get(p.serial) : null) ??
|
||||
livePrinters.find(
|
||||
(lp) => lp.agentId === agent.id && lp.serial === p.serial,
|
||||
);
|
||||
|
||||
return (
|
||||
<Box
|
||||
key={p.id}
|
||||
sx={{
|
||||
p: 1.25,
|
||||
borderRadius: 1,
|
||||
border: '1px solid',
|
||||
borderColor: 'divider',
|
||||
bgcolor: 'background.paper',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'space-between',
|
||||
gap: 1.5,
|
||||
flexWrap: 'wrap',
|
||||
opacity: pEnabled ? 1 : 0.65,
|
||||
transition: 'opacity 0.2s ease',
|
||||
}}
|
||||
>
|
||||
<Box sx={{ display: 'flex', alignItems: 'center', gap: 1, flexWrap: 'wrap' }}>
|
||||
<PrintOutlinedIcon sx={{ fontSize: 20, color: 'text.secondary' }} />
|
||||
<Typography variant="body2" fontWeight={600}>
|
||||
{p.model || 'Drucker'}
|
||||
</Typography>
|
||||
{p.type ? (
|
||||
<Chip
|
||||
label={p.type.toUpperCase()}
|
||||
size="small"
|
||||
color="primary"
|
||||
variant="outlined"
|
||||
sx={{ fontWeight: 600, fontSize: '0.7rem', height: 20 }}
|
||||
/>
|
||||
) : null}
|
||||
{p.serial ? (
|
||||
<Typography
|
||||
variant="caption"
|
||||
color="text.secondary"
|
||||
sx={{ fontFamily: 'monospace' }}
|
||||
>
|
||||
({p.serial})
|
||||
</Typography>
|
||||
) : null}
|
||||
{renderPrinterDiagnostics(p, live)}
|
||||
</Box>
|
||||
|
||||
<Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>
|
||||
{/* Test print button */}
|
||||
<Tooltip title="Test-Etikett an Drucker senden (ZPL)">
|
||||
<span>
|
||||
<Button
|
||||
size="small"
|
||||
variant="outlined"
|
||||
color="primary"
|
||||
startIcon={<PrintOutlinedIcon sx={{ fontSize: 15 }} />}
|
||||
disabled={testingPrinterId === p.id}
|
||||
onClick={() => void this.handleTestPrint(p)}
|
||||
sx={{
|
||||
textTransform: 'none',
|
||||
fontSize: '0.75rem',
|
||||
py: 0.25,
|
||||
px: 1,
|
||||
minHeight: 26,
|
||||
fontWeight: 600,
|
||||
}}
|
||||
>
|
||||
{testingPrinterId === p.id ? 'Druckt…' : 'Testdruck'}
|
||||
</Button>
|
||||
</span>
|
||||
</Tooltip>
|
||||
|
||||
{/* Enabled toggle switch */}
|
||||
<FormControlLabel
|
||||
control={
|
||||
<Switch
|
||||
size="small"
|
||||
checked={pEnabled}
|
||||
onChange={(e) =>
|
||||
void this.handleTogglePrinterEnabled(p, e.target.checked)
|
||||
}
|
||||
/>
|
||||
}
|
||||
label={
|
||||
<Typography
|
||||
variant="caption"
|
||||
color={pEnabled ? 'text.primary' : 'text.disabled'}
|
||||
>
|
||||
{pEnabled ? 'Aktiv' : 'Inaktiv'}
|
||||
</Typography>
|
||||
}
|
||||
sx={{ m: 0 }}
|
||||
/>
|
||||
|
||||
{/* Reorder buttons */}
|
||||
<Box sx={{ display: 'flex', alignItems: 'center' }}>
|
||||
<Tooltip title="Nach oben verschieben">
|
||||
<span>
|
||||
<IconButton
|
||||
size="small"
|
||||
disabled={pIdx === 0}
|
||||
onClick={() => void this.handleMovePrinter(p, 'up')}
|
||||
sx={{ p: 0.25 }}
|
||||
>
|
||||
<ArrowUpwardIcon sx={{ fontSize: 16 }} />
|
||||
</IconButton>
|
||||
</span>
|
||||
</Tooltip>
|
||||
<Tooltip title="Nach unten verschieben">
|
||||
<span>
|
||||
<IconButton
|
||||
size="small"
|
||||
disabled={pIdx === printersForAgent.length - 1}
|
||||
onClick={() => void this.handleMovePrinter(p, 'down')}
|
||||
sx={{ p: 0.25 }}
|
||||
>
|
||||
<ArrowDownwardIcon sx={{ fontSize: 16 }} />
|
||||
</IconButton>
|
||||
</span>
|
||||
</Tooltip>
|
||||
</Box>
|
||||
|
||||
{/* Delete printer button */}
|
||||
<Tooltip title="Drucker entfernen">
|
||||
<IconButton
|
||||
size="small"
|
||||
color="error"
|
||||
onClick={() => void this.handleDeletePrinter(p)}
|
||||
sx={{ p: 0.5 }}
|
||||
>
|
||||
<DeleteOutlinedIcon sx={{ fontSize: 18 }} />
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
})}
|
||||
</Box>
|
||||
)}
|
||||
</Box>
|
||||
)}
|
||||
|
||||
{/* Agent sort order controls */}
|
||||
<Box
|
||||
@@ -1052,7 +873,6 @@ export default class PrinterAgentSettingsPanel extends PureComponent {
|
||||
<Typography variant="body2" color="text.secondary">
|
||||
Reihenfolge:
|
||||
</Typography>
|
||||
<Tooltip title="Nach oben verschieben">
|
||||
<span>
|
||||
<IconButton
|
||||
size="small"
|
||||
@@ -1063,8 +883,6 @@ export default class PrinterAgentSettingsPanel extends PureComponent {
|
||||
<ArrowUpwardIcon sx={{ fontSize: 16 }} />
|
||||
</IconButton>
|
||||
</span>
|
||||
</Tooltip>
|
||||
<Tooltip title="Nach unten verschieben">
|
||||
<span>
|
||||
<IconButton
|
||||
size="small"
|
||||
@@ -1075,7 +893,6 @@ export default class PrinterAgentSettingsPanel extends PureComponent {
|
||||
<ArrowDownwardIcon sx={{ fontSize: 16 }} />
|
||||
</IconButton>
|
||||
</span>
|
||||
</Tooltip>
|
||||
<TextField
|
||||
type="number"
|
||||
size="small"
|
||||
@@ -1128,6 +945,187 @@ export default class PrinterAgentSettingsPanel extends PureComponent {
|
||||
})}
|
||||
</Box>
|
||||
)}
|
||||
|
||||
{/* Separate Printers Section */}
|
||||
<Divider sx={{ my: 4 }} />
|
||||
|
||||
<Box sx={{ mb: 2 }}>
|
||||
<Typography variant="h6" fontWeight={600} gutterBottom>
|
||||
Drucker
|
||||
</Typography>
|
||||
</Box>
|
||||
|
||||
{agentprinters.length === 0 ? (
|
||||
<Box
|
||||
sx={{
|
||||
textAlign: 'center',
|
||||
py: 5,
|
||||
color: 'text.secondary',
|
||||
bgcolor: 'action.hover',
|
||||
borderRadius: 2,
|
||||
border: '1px dashed',
|
||||
borderColor: 'divider',
|
||||
}}
|
||||
>
|
||||
<PrintOutlinedIcon sx={{ fontSize: 44, mb: 1, opacity: 0.5 }} />
|
||||
<Typography variant="body2">
|
||||
Keine Drucker erkannt. Schließen Sie Drucker per USB an einen gekoppelten Drucker-Agenten an.
|
||||
</Typography>
|
||||
</Box>
|
||||
) : (
|
||||
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 1.5 }}>
|
||||
{agentprinters.map((p, pIdx) => {
|
||||
const pEnabled = p.enabled !== false;
|
||||
const live =
|
||||
(p.serial ? livePrintersBySerial.get(p.serial) : null) ??
|
||||
livePrinters.find(
|
||||
(lp) => lp.agentId === p.printeragentId && lp.serial === p.serial,
|
||||
);
|
||||
const isOnline = Boolean(
|
||||
p.online ?? (live ? !live.unreachable && live.status !== 'offline' : false),
|
||||
);
|
||||
const parentAgent = agentMap.get(p.printeragentId);
|
||||
|
||||
return (
|
||||
<Box
|
||||
key={p.id}
|
||||
sx={{
|
||||
p: 1.5,
|
||||
borderRadius: 1.5,
|
||||
border: '1px solid',
|
||||
borderColor: 'divider',
|
||||
bgcolor: 'background.paper',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'space-between',
|
||||
gap: 1.5,
|
||||
flexWrap: 'wrap',
|
||||
opacity: pEnabled ? 1 : 0.65,
|
||||
transition: 'opacity 0.2s ease',
|
||||
}}
|
||||
>
|
||||
<Box sx={{ display: 'flex', alignItems: 'center', gap: 1, flexWrap: 'wrap' }}>
|
||||
<PrintOutlinedIcon sx={{ fontSize: 22, color: 'text.secondary' }} />
|
||||
<Typography variant="body2" fontWeight={600}>
|
||||
{p.model || 'Drucker'}
|
||||
</Typography>
|
||||
{p.type ? (
|
||||
<Chip
|
||||
label={p.type.toUpperCase()}
|
||||
size="small"
|
||||
color="primary"
|
||||
variant="outlined"
|
||||
sx={{ fontWeight: 600, fontSize: '0.7rem', height: 20 }}
|
||||
/>
|
||||
) : null}
|
||||
{p.serial ? (
|
||||
<Typography
|
||||
variant="caption"
|
||||
color="text.secondary"
|
||||
sx={{ fontFamily: 'monospace' }}
|
||||
>
|
||||
({p.serial})
|
||||
</Typography>
|
||||
) : null}
|
||||
{parentAgent ? (
|
||||
<Chip
|
||||
label={`Agent: ${parentAgent.name}`}
|
||||
size="small"
|
||||
variant="outlined"
|
||||
sx={{ fontSize: '0.7rem', height: 20 }}
|
||||
/>
|
||||
) : null}
|
||||
{renderPrinterDiagnostics(p, live)}
|
||||
</Box>
|
||||
|
||||
<Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>
|
||||
{/* Test print button */}
|
||||
<span>
|
||||
<Button
|
||||
size="small"
|
||||
variant="outlined"
|
||||
color="primary"
|
||||
startIcon={<PrintOutlinedIcon sx={{ fontSize: 15 }} />}
|
||||
disabled={testingPrinterId === p.id}
|
||||
onClick={() => void this.handleTestPrint(p)}
|
||||
sx={{
|
||||
textTransform: 'none',
|
||||
fontSize: '0.75rem',
|
||||
py: 0.25,
|
||||
px: 1,
|
||||
minHeight: 26,
|
||||
fontWeight: 600,
|
||||
}}
|
||||
>
|
||||
{testingPrinterId === p.id ? 'Druckt…' : 'Testdruck'}
|
||||
</Button>
|
||||
</span>
|
||||
|
||||
{/* Enabled toggle switch */}
|
||||
<FormControlLabel
|
||||
control={
|
||||
<Switch
|
||||
size="small"
|
||||
checked={pEnabled}
|
||||
onChange={(e) =>
|
||||
void this.handleTogglePrinterEnabled(p, e.target.checked)
|
||||
}
|
||||
/>
|
||||
}
|
||||
label={
|
||||
<Typography
|
||||
variant="caption"
|
||||
color={pEnabled ? 'text.primary' : 'text.disabled'}
|
||||
>
|
||||
{pEnabled ? 'Aktiv' : 'Inaktiv'}
|
||||
</Typography>
|
||||
}
|
||||
sx={{ m: 0 }}
|
||||
/>
|
||||
|
||||
{/* Reorder buttons across all printers */}
|
||||
<Box sx={{ display: 'flex', alignItems: 'center' }}>
|
||||
<span>
|
||||
<IconButton
|
||||
size="small"
|
||||
disabled={pIdx === 0}
|
||||
onClick={() => void this.handleMovePrinter(p, 'up')}
|
||||
sx={{ p: 0.25 }}
|
||||
>
|
||||
<ArrowUpwardIcon sx={{ fontSize: 16 }} />
|
||||
</IconButton>
|
||||
</span>
|
||||
|
||||
<span>
|
||||
<IconButton
|
||||
size="small"
|
||||
disabled={pIdx === agentprinters.length - 1}
|
||||
onClick={() => void this.handleMovePrinter(p, 'down')}
|
||||
sx={{ p: 0.25 }}
|
||||
>
|
||||
<ArrowDownwardIcon sx={{ fontSize: 16 }} />
|
||||
</IconButton>
|
||||
</span>
|
||||
</Box>
|
||||
|
||||
{/* Delete printer button: disabled when online! */}
|
||||
<span>
|
||||
<IconButton
|
||||
size="small"
|
||||
color="error"
|
||||
disabled={isOnline}
|
||||
onClick={() => void this.handleDeletePrinter(p)}
|
||||
sx={{ p: 0.5 }}
|
||||
>
|
||||
<DeleteOutlinedIcon sx={{ fontSize: 18 }} />
|
||||
</IconButton>
|
||||
</span>
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
})}
|
||||
</Box>
|
||||
)}
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -5,7 +5,6 @@ import CircularProgress from '@mui/material/CircularProgress';
|
||||
import ListItemButton from '@mui/material/ListItemButton';
|
||||
import Typography from '@mui/material/Typography';
|
||||
import Skeleton from '@mui/material/Skeleton';
|
||||
import Tooltip from '@mui/material/Tooltip';
|
||||
import ViewModuleIcon from '@mui/icons-material/ViewModule';
|
||||
import Chip from '@mui/material/Chip';
|
||||
import SingleLineTextEdit from 'dashgui/SingleLineTextEdit';
|
||||
@@ -207,11 +206,9 @@ class GlobalHistoryRow extends PureComponent {
|
||||
|
||||
{/* 4. Meldung / Beschreibung */}
|
||||
<Box sx={{ gridColumn: 4, gridRow: 2, minWidth: 0 }}>
|
||||
<Tooltip title={item.text || item.value || ''} placement="top-start" enterDelay={500}>
|
||||
<Typography variant="body2" sx={ellipsisSx}>
|
||||
{item.text || item.value || '–'}
|
||||
</Typography>
|
||||
</Tooltip>
|
||||
</Box>
|
||||
</ListItemButton>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user