feat: add default label template setting and apply it to print dialog selection
Build and Push Multi-Platform Images / build-and-push (push) Successful in 35s

This commit is contained in:
2026-05-09 12:41:05 +02:00
parent e4f765fcfd
commit 0318fe8e7a
5 changed files with 82 additions and 5 deletions
@@ -9,6 +9,7 @@ export interface UserSettingsData {
smtpFrom: string | null;
smtpFromName: string | null;
mailSignatureHtml: string | null;
defaultLabelTemplateId: number | null;
}
export interface SenderOption {
+13 -4
View File
@@ -36,6 +36,7 @@ import type { ColumnsType } from 'antd/es/table';
import { inboxApi, type InboxBarcode, type InboxFile } from '../api/inbox';
import { barcodeTemplatesApi, type BarcodeTemplate } from '../api/barcode-templates';
import { labelPrintAgentApi } from '../api/labelPrintAgent';
import { userSettingsApi } from '../api/userSettings';
const { Title } = Typography;
@@ -150,14 +151,22 @@ export default function InboxPage() {
const openPrintDialog = async () => {
try {
const all = await barcodeTemplatesApi.list();
setLabelTemplates(all.filter((t) => t.LabelEnabled));
const [all, settings] = await Promise.all([
barcodeTemplatesApi.list(),
userSettingsApi.get(),
]);
const enabled = all.filter((t) => t.LabelEnabled);
setLabelTemplates(enabled);
const defaultId = settings.defaultLabelTemplateId;
const defaultTemplate = defaultId != null
? (enabled.find((t) => t.Id === defaultId) ?? null)
: null;
setSelectedTemplate(defaultTemplate);
setFieldValues(buildInitialFieldValues(defaultTemplate));
} catch {
message.error('Vorlagen konnten nicht geladen werden');
return;
}
setSelectedTemplate(null);
setFieldValues({});
setLabelCount(1);
setPrintDialogOpen(true);
};
@@ -1,11 +1,66 @@
import { useEffect, useRef, useState } from 'react';
import { Button, Card, Form, Input, InputNumber, Space, Switch, Tabs, Typography, message } from 'antd';
import { Button, Card, Form, Input, InputNumber, Select, Space, Switch, Tabs, Typography, message } from 'antd';
import { CheckCircleOutlined, CloseCircleOutlined, LoadingOutlined } from '@ant-design/icons';
import { WysiwygEditor, type WysiwygEditorHandle } from '../components/WysiwygEditor';
import { userSettingsApi } from '../api/userSettings';
import { barcodeTemplatesApi, type BarcodeTemplate } from '../api/barcode-templates';
const { Title } = Typography;
function LabelSettingsTab() {
const [templates, setTemplates] = useState<BarcodeTemplate[]>([]);
const [selectedId, setSelectedId] = useState<number | null>(null);
const [loading, setLoading] = useState(true);
const [saving, setSaving] = useState(false);
useEffect(() => {
Promise.all([userSettingsApi.get(), barcodeTemplatesApi.list()])
.then(([settings, all]) => {
setTemplates(all.filter((t) => t.LabelEnabled));
setSelectedId(settings.defaultLabelTemplateId);
})
.catch(() => message.error('Einstellungen konnten nicht geladen werden'))
.finally(() => setLoading(false));
}, []);
const handleSave = async () => {
setSaving(true);
try {
await userSettingsApi.update({ defaultLabelTemplateId: selectedId });
message.success('Einstellungen gespeichert');
} catch {
message.error('Speichern fehlgeschlagen');
} finally {
setSaving(false);
}
};
if (loading) return null;
return (
<Form layout="vertical" style={{ maxWidth: 600 }}>
<Form.Item
label="Standard-Etikettenvorlage"
extra="Diese Vorlage wird beim Öffnen des Etikett-drucken-Dialogs vorausgewählt."
>
<Select
placeholder="Keine Standardvorlage"
allowClear
options={templates.map((t) => ({ value: t.Id, label: t.Name }))}
value={selectedId ?? undefined}
onChange={(v: number | undefined) => setSelectedId(v ?? null)}
style={{ width: '100%' }}
/>
</Form.Item>
<Form.Item>
<Button type="primary" loading={saving} onClick={handleSave}>
Speichern
</Button>
</Form.Item>
</Form>
);
}
function MailSettingsTab() {
const [form] = Form.useForm();
const [loading, setLoading] = useState(true);
@@ -155,6 +210,11 @@ export default function UserSettingsPage() {
label: 'Maileinstellungen',
children: <MailSettingsTab />,
},
{
key: 'label',
label: 'Etikettendruck',
children: <LabelSettingsTab />,
},
]}
/>
</Card>