fix: fehlende Dateien fuer Etiketten-Elemente-Umbau nachreichen
git add -u im letzten Commit hat neue (untracked) Dateien übersprungen: die Migration für LabelTemplate.elements, die neuen Typ-/DTO-Dateien und den kompletten Drag-and-Drop-Editor fehlten dadurch im Build.
This commit is contained in:
1 parent
5f4e1a7ba9
commit
938239e16e
9 files changed
+1134
No files matched your search
@@ -0,0 +1,116 @@
|
||||
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
|
||||
import {
|
||||
IsBoolean,
|
||||
IsIn,
|
||||
IsNumber,
|
||||
IsOptional,
|
||||
IsString,
|
||||
MaxLength,
|
||||
} from 'class-validator';
|
||||
import { PLACEHOLDER_KEYS } from '../label-element.types';
|
||||
|
||||
const ELEMENT_TYPES = ['text', 'qrCode', 'image', 'line'] as const;
|
||||
const FONT_FAMILIES = ['sans', 'serif', 'mono'] as const;
|
||||
const TEXT_ALIGNS = ['left', 'center', 'right'] as const;
|
||||
const LINE_ORIENTATIONS = ['horizontal', 'vertical'] as const;
|
||||
|
||||
// One DTO shared by all element types rather than a discriminated-union of
|
||||
// four DTOs: this is an internal, permission-gated design surface (not
|
||||
// public input), so the pragmatic boundary check is "every field has the
|
||||
// right primitive type" - the service picks which fields it reads per
|
||||
// `type` at render time.
|
||||
export class LabelElementDto {
|
||||
@ApiProperty()
|
||||
@IsString()
|
||||
id!: string;
|
||||
|
||||
@ApiProperty({ enum: ELEMENT_TYPES })
|
||||
@IsIn(ELEMENT_TYPES)
|
||||
type!: (typeof ELEMENT_TYPES)[number];
|
||||
|
||||
@ApiProperty()
|
||||
@IsNumber()
|
||||
x!: number;
|
||||
|
||||
@ApiProperty()
|
||||
@IsNumber()
|
||||
y!: number;
|
||||
|
||||
@ApiPropertyOptional()
|
||||
@IsOptional()
|
||||
@IsNumber()
|
||||
width?: number;
|
||||
|
||||
@ApiPropertyOptional()
|
||||
@IsOptional()
|
||||
@IsNumber()
|
||||
height?: number;
|
||||
|
||||
@ApiPropertyOptional()
|
||||
@IsOptional()
|
||||
@IsNumber()
|
||||
size?: number;
|
||||
|
||||
@ApiPropertyOptional()
|
||||
@IsOptional()
|
||||
@IsNumber()
|
||||
length?: number;
|
||||
|
||||
@ApiPropertyOptional()
|
||||
@IsOptional()
|
||||
@IsNumber()
|
||||
thickness?: number;
|
||||
|
||||
@ApiPropertyOptional({ description: 'text-Element: literaler Text' })
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
@MaxLength(500)
|
||||
text?: string;
|
||||
|
||||
@ApiPropertyOptional({ enum: PLACEHOLDER_KEYS })
|
||||
@IsOptional()
|
||||
@IsIn(PLACEHOLDER_KEYS)
|
||||
placeholderKey?: (typeof PLACEHOLDER_KEYS)[number] | null;
|
||||
|
||||
@ApiPropertyOptional()
|
||||
@IsOptional()
|
||||
@IsNumber()
|
||||
fontSize?: number;
|
||||
|
||||
@ApiPropertyOptional({ enum: FONT_FAMILIES })
|
||||
@IsOptional()
|
||||
@IsIn(FONT_FAMILIES)
|
||||
fontFamily?: (typeof FONT_FAMILIES)[number];
|
||||
|
||||
@ApiPropertyOptional()
|
||||
@IsOptional()
|
||||
@IsBoolean()
|
||||
bold?: boolean;
|
||||
|
||||
@ApiPropertyOptional()
|
||||
@IsOptional()
|
||||
@IsBoolean()
|
||||
italic?: boolean;
|
||||
|
||||
@ApiPropertyOptional()
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
@MaxLength(20)
|
||||
color?: string;
|
||||
|
||||
@ApiPropertyOptional({ enum: TEXT_ALIGNS })
|
||||
@IsOptional()
|
||||
@IsIn(TEXT_ALIGNS)
|
||||
align?: (typeof TEXT_ALIGNS)[number];
|
||||
|
||||
@ApiPropertyOptional({ enum: LINE_ORIENTATIONS })
|
||||
@IsOptional()
|
||||
@IsIn(LINE_ORIENTATIONS)
|
||||
orientation?: (typeof LINE_ORIENTATIONS)[number];
|
||||
|
||||
@ApiPropertyOptional({ description: 'image-Element: data: URL (PNG/JPEG)' })
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
@MaxLength(3_000_000)
|
||||
src?: string;
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
export type LabelFontFamily = 'sans' | 'serif' | 'mono';
|
||||
export type LabelTextAlign = 'left' | 'center' | 'right';
|
||||
export type LabelLineOrientation = 'horizontal' | 'vertical';
|
||||
|
||||
export const PLACEHOLDER_KEYS = [
|
||||
'batchNumber',
|
||||
'honeyType',
|
||||
'lotNumber',
|
||||
'bottlingDate',
|
||||
'bestBeforeDate',
|
||||
'jarSize',
|
||||
'productName',
|
||||
] as const;
|
||||
export type PlaceholderKey = (typeof PLACEHOLDER_KEYS)[number];
|
||||
|
||||
interface LabelElementBase {
|
||||
id: string;
|
||||
x: number;
|
||||
y: number;
|
||||
}
|
||||
|
||||
export interface LabelTextElement extends LabelElementBase {
|
||||
type: 'text';
|
||||
width: number;
|
||||
height: number;
|
||||
text: string;
|
||||
placeholderKey?: PlaceholderKey | null;
|
||||
fontSize: number;
|
||||
fontFamily: LabelFontFamily;
|
||||
bold: boolean;
|
||||
italic: boolean;
|
||||
color: string;
|
||||
align: LabelTextAlign;
|
||||
}
|
||||
|
||||
export interface LabelQrCodeElement extends LabelElementBase {
|
||||
type: 'qrCode';
|
||||
size: number;
|
||||
}
|
||||
|
||||
export interface LabelImageElement extends LabelElementBase {
|
||||
type: 'image';
|
||||
width: number;
|
||||
height: number;
|
||||
src: string;
|
||||
}
|
||||
|
||||
export interface LabelLineElement extends LabelElementBase {
|
||||
type: 'line';
|
||||
length: number;
|
||||
thickness: number;
|
||||
color: string;
|
||||
orientation: LabelLineOrientation;
|
||||
}
|
||||
|
||||
export type LabelElement =
|
||||
LabelTextElement | LabelQrCodeElement | LabelImageElement | LabelLineElement;
|
||||
Reference in new issue
Block a user