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
Build and Push Multi-Platform Images / build-and-push (push) Successful in 35s
This commit is contained in:
@@ -28,4 +28,7 @@ export class UserSettings {
|
|||||||
|
|
||||||
@Column({ type: 'text', nullable: true })
|
@Column({ type: 'text', nullable: true })
|
||||||
MailSignatureHtml!: string | null;
|
MailSignatureHtml!: string | null;
|
||||||
|
|
||||||
|
@Column({ type: 'int', nullable: true })
|
||||||
|
DefaultLabelTemplateId!: number | null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ export interface UserSettingsDto {
|
|||||||
smtpFrom: string | null;
|
smtpFrom: string | null;
|
||||||
smtpFromName: string | null;
|
smtpFromName: string | null;
|
||||||
mailSignatureHtml: string | null;
|
mailSignatureHtml: string | null;
|
||||||
|
defaultLabelTemplateId: number | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
@@ -78,6 +79,7 @@ export class UserSettingsService {
|
|||||||
smtpFrom?: string | null;
|
smtpFrom?: string | null;
|
||||||
smtpFromName?: string | null;
|
smtpFromName?: string | null;
|
||||||
mailSignatureHtml?: string | null;
|
mailSignatureHtml?: string | null;
|
||||||
|
defaultLabelTemplateId?: number | null;
|
||||||
},
|
},
|
||||||
): Promise<UserSettingsDto> {
|
): Promise<UserSettingsDto> {
|
||||||
let entity = await this.repo.findOne({ where: { UserId: userId } });
|
let entity = await this.repo.findOne({ where: { UserId: userId } });
|
||||||
@@ -95,6 +97,7 @@ export class UserSettingsService {
|
|||||||
if (data.smtpFrom !== undefined) entity.SmtpFrom = data.smtpFrom;
|
if (data.smtpFrom !== undefined) entity.SmtpFrom = data.smtpFrom;
|
||||||
if (data.smtpFromName !== undefined) entity.SmtpFromName = data.smtpFromName;
|
if (data.smtpFromName !== undefined) entity.SmtpFromName = data.smtpFromName;
|
||||||
if (data.mailSignatureHtml !== undefined) entity.MailSignatureHtml = data.mailSignatureHtml;
|
if (data.mailSignatureHtml !== undefined) entity.MailSignatureHtml = data.mailSignatureHtml;
|
||||||
|
if (data.defaultLabelTemplateId !== undefined) entity.DefaultLabelTemplateId = data.defaultLabelTemplateId;
|
||||||
|
|
||||||
await this.repo.save(entity);
|
await this.repo.save(entity);
|
||||||
return this.toDto(entity);
|
return this.toDto(entity);
|
||||||
@@ -164,6 +167,7 @@ export class UserSettingsService {
|
|||||||
smtpFrom: entity?.SmtpFrom ?? null,
|
smtpFrom: entity?.SmtpFrom ?? null,
|
||||||
smtpFromName: entity?.SmtpFromName ?? null,
|
smtpFromName: entity?.SmtpFromName ?? null,
|
||||||
mailSignatureHtml: entity?.MailSignatureHtml ?? null,
|
mailSignatureHtml: entity?.MailSignatureHtml ?? null,
|
||||||
|
defaultLabelTemplateId: entity?.DefaultLabelTemplateId ?? null,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ export interface UserSettingsData {
|
|||||||
smtpFrom: string | null;
|
smtpFrom: string | null;
|
||||||
smtpFromName: string | null;
|
smtpFromName: string | null;
|
||||||
mailSignatureHtml: string | null;
|
mailSignatureHtml: string | null;
|
||||||
|
defaultLabelTemplateId: number | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface SenderOption {
|
export interface SenderOption {
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ import type { ColumnsType } from 'antd/es/table';
|
|||||||
import { inboxApi, type InboxBarcode, type InboxFile } from '../api/inbox';
|
import { inboxApi, type InboxBarcode, type InboxFile } from '../api/inbox';
|
||||||
import { barcodeTemplatesApi, type BarcodeTemplate } from '../api/barcode-templates';
|
import { barcodeTemplatesApi, type BarcodeTemplate } from '../api/barcode-templates';
|
||||||
import { labelPrintAgentApi } from '../api/labelPrintAgent';
|
import { labelPrintAgentApi } from '../api/labelPrintAgent';
|
||||||
|
import { userSettingsApi } from '../api/userSettings';
|
||||||
|
|
||||||
const { Title } = Typography;
|
const { Title } = Typography;
|
||||||
|
|
||||||
@@ -150,14 +151,22 @@ export default function InboxPage() {
|
|||||||
|
|
||||||
const openPrintDialog = async () => {
|
const openPrintDialog = async () => {
|
||||||
try {
|
try {
|
||||||
const all = await barcodeTemplatesApi.list();
|
const [all, settings] = await Promise.all([
|
||||||
setLabelTemplates(all.filter((t) => t.LabelEnabled));
|
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 {
|
} catch {
|
||||||
message.error('Vorlagen konnten nicht geladen werden');
|
message.error('Vorlagen konnten nicht geladen werden');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
setSelectedTemplate(null);
|
|
||||||
setFieldValues({});
|
|
||||||
setLabelCount(1);
|
setLabelCount(1);
|
||||||
setPrintDialogOpen(true);
|
setPrintDialogOpen(true);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,11 +1,66 @@
|
|||||||
import { useEffect, useRef, useState } from 'react';
|
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 { CheckCircleOutlined, CloseCircleOutlined, LoadingOutlined } from '@ant-design/icons';
|
||||||
import { WysiwygEditor, type WysiwygEditorHandle } from '../components/WysiwygEditor';
|
import { WysiwygEditor, type WysiwygEditorHandle } from '../components/WysiwygEditor';
|
||||||
import { userSettingsApi } from '../api/userSettings';
|
import { userSettingsApi } from '../api/userSettings';
|
||||||
|
import { barcodeTemplatesApi, type BarcodeTemplate } from '../api/barcode-templates';
|
||||||
|
|
||||||
const { Title } = Typography;
|
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() {
|
function MailSettingsTab() {
|
||||||
const [form] = Form.useForm();
|
const [form] = Form.useForm();
|
||||||
const [loading, setLoading] = useState(true);
|
const [loading, setLoading] = useState(true);
|
||||||
@@ -155,6 +210,11 @@ export default function UserSettingsPage() {
|
|||||||
label: 'Maileinstellungen',
|
label: 'Maileinstellungen',
|
||||||
children: <MailSettingsTab />,
|
children: <MailSettingsTab />,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
key: 'label',
|
||||||
|
label: 'Etikettendruck',
|
||||||
|
children: <LabelSettingsTab />,
|
||||||
|
},
|
||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
</Card>
|
</Card>
|
||||||
|
|||||||
Reference in New Issue
Block a user