feat: add label configuration fields to barcode templates and implement zero-padding support in variable replacement
Build and Push Multi-Platform Images / build-and-push (push) Successful in 27s

This commit is contained in:
2026-05-07 23:34:52 +02:00
parent 80f862a0c0
commit 71502df7b4
3 changed files with 47 additions and 3 deletions
@@ -13,7 +13,7 @@ import {
} from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { BarcodeTemplate, type BarcodeActionType } from '../database/entities/barcode-template.entity';
import { BarcodeTemplate, type BarcodeActionType, type LabelInputField, type LabelElement } from '../database/entities/barcode-template.entity';
import { RequirePermissions } from '../auth/permissions.decorator';
import { Permission } from '../auth/permissions.enum';
import { BarcodeScannerService } from './barcode-scanner.service';
@@ -26,6 +26,14 @@ interface UpsertDto {
SplitBefore?: boolean;
DateinameTemplate?: string | null;
Actions?: BarcodeActionType[];
LabelEnabled?: boolean;
LabelWidthMm?: number | null;
LabelHeightMm?: number | null;
LabelInputFields?: LabelInputField[] | null;
LabelGetUrl?: string | null;
LabelPrintedUrl?: string | null;
LabelReleaseUrl?: string | null;
LabelLayout?: LabelElement[] | null;
}
function validate(dto: UpsertDto, partial = false): void {
@@ -94,6 +102,14 @@ export class BarcodeTemplatesController {
SplitBefore: dto.SplitBefore ?? false,
DateinameTemplate: dto.DateinameTemplate ?? null,
Actions: dto.Actions!,
LabelEnabled: dto.LabelEnabled ?? false,
LabelWidthMm: dto.LabelWidthMm ?? null,
LabelHeightMm: dto.LabelHeightMm ?? null,
LabelInputFields: dto.LabelInputFields ?? null,
LabelGetUrl: dto.LabelGetUrl ?? null,
LabelPrintedUrl: dto.LabelPrintedUrl ?? null,
LabelReleaseUrl: dto.LabelReleaseUrl ?? null,
LabelLayout: dto.LabelLayout ?? null,
});
const saved = await this.repo.save(entity);
this.scanner.invalidateTemplates();
@@ -114,6 +130,14 @@ export class BarcodeTemplatesController {
if (dto.SplitBefore !== undefined) existing.SplitBefore = dto.SplitBefore;
if (dto.DateinameTemplate !== undefined) existing.DateinameTemplate = dto.DateinameTemplate ?? null;
if (dto.Actions !== undefined) existing.Actions = dto.Actions;
if (dto.LabelEnabled !== undefined) existing.LabelEnabled = dto.LabelEnabled;
if (dto.LabelWidthMm !== undefined) existing.LabelWidthMm = dto.LabelWidthMm ?? null;
if (dto.LabelHeightMm !== undefined) existing.LabelHeightMm = dto.LabelHeightMm ?? null;
if (dto.LabelInputFields !== undefined) existing.LabelInputFields = dto.LabelInputFields ?? null;
if (dto.LabelGetUrl !== undefined) existing.LabelGetUrl = dto.LabelGetUrl ?? null;
if (dto.LabelPrintedUrl !== undefined) existing.LabelPrintedUrl = dto.LabelPrintedUrl ?? null;
if (dto.LabelReleaseUrl !== undefined) existing.LabelReleaseUrl = dto.LabelReleaseUrl ?? null;
if (dto.LabelLayout !== undefined) existing.LabelLayout = dto.LabelLayout ?? null;
const saved = await this.repo.save(existing);
this.scanner.invalidateTemplates();
@@ -6,7 +6,17 @@ import { BarcodeTemplate } from '../database/entities/barcode-template.entity';
import { LabelRendererService } from './label-renderer.service';
function applyVars(template: string, vars: Record<string, string>): string {
return template.replace(/\{([^}]+)\}/g, (_, key) => vars[key] ?? '');
return template.replace(/\{([^}]+)\}/g, (_, key: string) => {
const colonIdx = key.indexOf(':');
if (colonIdx !== -1) {
const varName = key.slice(0, colonIdx);
const width = parseInt(key.slice(colonIdx + 1), 10);
if (!isNaN(width) && varName in vars) {
return vars[varName].padStart(width, '0');
}
}
return vars[key] ?? '';
});
}
function lockExpiry(): Date {
@@ -14,7 +14,17 @@ function escape(s: string): string {
}
function applyVars(template: string, vars: Record<string, string>): string {
return template.replace(/\{([^}]+)\}/g, (_, key) => vars[key] ?? `{${key}}`);
return template.replace(/\{([^}]+)\}/g, (_, key: string) => {
const colonIdx = key.indexOf(':');
if (colonIdx !== -1) {
const varName = key.slice(0, colonIdx);
const width = parseInt(key.slice(colonIdx + 1), 10);
if (!isNaN(width) && varName in vars) {
return vars[varName].padStart(width, '0');
}
}
return vars[key] ?? `{${key}}`;
});
}
@Injectable()