diff --git a/src-ui/src/app/components/manage/ocr-templates/ocr-template-editor/ocr-template-editor-zone-list/ocr-template-editor-zone-list.component.html b/src-ui/src/app/components/manage/ocr-templates/ocr-template-editor/ocr-template-editor-zone-list/ocr-template-editor-zone-list.component.html index 34c337ed1..ca18f77b7 100644 --- a/src-ui/src/app/components/manage/ocr-templates/ocr-template-editor/ocr-template-editor-zone-list/ocr-template-editor-zone-list.component.html +++ b/src-ui/src/app/components/manage/ocr-templates/ocr-template-editor/ocr-template-editor-zone-list/ocr-template-editor-zone-list.component.html @@ -1,34 +1,25 @@ @if (zones.length === 0) { -

- No zones defined. -

-} - -
- @for (zone of zones; track $index; let i = $index) { -
-
-
- - {{ zone.name }} - +

No zones yet. Use Draw to outline one on the sample document.

+} @else { +
+ @for (zone of zones; track $index; let i = $index) { +
+ +
+ +
{{ getZoneTargetName(zone) }}
-
- {{ getZoneTargetName(zone) }} - {{ zone.width }}x{{ zone.height }}px - p.{{ zonePage(zone) }} -
-
-
- -
-
- } -
+ } +
+} diff --git a/src-ui/src/app/components/manage/ocr-templates/ocr-template-editor/ocr-template-editor-zone-list/ocr-template-editor-zone-list.component.spec.ts b/src-ui/src/app/components/manage/ocr-templates/ocr-template-editor/ocr-template-editor-zone-list/ocr-template-editor-zone-list.component.spec.ts index a7895fcee..a9e41d1fe 100644 --- a/src-ui/src/app/components/manage/ocr-templates/ocr-template-editor/ocr-template-editor-zone-list/ocr-template-editor-zone-list.component.spec.ts +++ b/src-ui/src/app/components/manage/ocr-templates/ocr-template-editor/ocr-template-editor-zone-list/ocr-template-editor-zone-list.component.spec.ts @@ -41,19 +41,19 @@ describe('OcrTemplateEditorZoneListComponent', () => { it('shows empty state when no zones are defined', () => { fixture.detectChanges() - expect(fixture.nativeElement.textContent).toContain('No zones defined') + expect(fixture.nativeElement.textContent).toContain('No zones yet') }) - it('renders zone target, size, and page', () => { - component.zones = [zone()] + it('renders zone name, target, and page', () => { + component.zones = [zone(), zone({ name: 'Zone 2', page: -1 })] component.customFields = [{ id: 7, name: 'Invoice Number' } as CustomField] fixture.detectChanges() const text = fixture.nativeElement.textContent expect(text).toContain('Zone 1') expect(text).toContain('Invoice Number') - expect(text).toContain('30x40px') - expect(text).toContain('p.1') + expect(text).toContain('Page 1') + expect(text).toContain('Last page') }) it('emits select and remove events', () => { diff --git a/src-ui/src/app/components/manage/ocr-templates/ocr-template-editor/ocr-template-editor-zone-list/ocr-template-editor-zone-list.component.ts b/src-ui/src/app/components/manage/ocr-templates/ocr-template-editor/ocr-template-editor-zone-list/ocr-template-editor-zone-list.component.ts index 0a633842c..9867e1d10 100644 --- a/src-ui/src/app/components/manage/ocr-templates/ocr-template-editor/ocr-template-editor-zone-list/ocr-template-editor-zone-list.component.ts +++ b/src-ui/src/app/components/manage/ocr-templates/ocr-template-editor/ocr-template-editor-zone-list/ocr-template-editor-zone-list.component.ts @@ -2,7 +2,7 @@ import { Component, EventEmitter, Input, Output } from '@angular/core' import { NgxBootstrapIconsModule } from 'ngx-bootstrap-icons' import { CustomField } from 'src/app/data/custom-field' import { OCR_BUILTIN_TARGETS, OcrTemplateZone } from 'src/app/data/ocr-template' -import { getZonePage } from '../zone-geometry' +import { getZoneColor } from '../zone-geometry' @Component({ selector: 'pngx-ocr-template-zone-list', @@ -11,17 +11,12 @@ import { getZonePage } from '../zone-geometry' }) export class OcrTemplateEditorZoneListComponent { @Input() zones: OcrTemplateZone[] = [] - @Input() selectedZoneIndex: number | null = null - @Input() previewPage = 0 - @Input() previewPageCount: number | null = null @Input() customFields: CustomField[] = [] @Output() zoneSelected = new EventEmitter() @Output() zoneRemoved = new EventEmitter() - zonePage(zone: OcrTemplateZone): number { - return getZonePage(zone, this.previewPage, this.previewPageCount) - } + readonly zoneColor = getZoneColor getZoneTargetName(zone: OcrTemplateZone): string { const target = zone.target || 'custom_field' diff --git a/src-ui/src/app/components/manage/ocr-templates/ocr-template-editor/ocr-template-editor.component.html b/src-ui/src/app/components/manage/ocr-templates/ocr-template-editor/ocr-template-editor.component.html index 235a9af1d..92ba66fb3 100644 --- a/src-ui/src/app/components/manage/ocr-templates/ocr-template-editor/ocr-template-editor.component.html +++ b/src-ui/src/app/components/manage/ocr-templates/ocr-template-editor/ocr-template-editor.component.html @@ -187,9 +187,6 @@ } @else { = { nw: 'nw-resize', ne: 'ne-resize', @@ -738,7 +729,7 @@ export class OcrTemplateEditorComponent implements OnInit, OnDestroy { } zoneColor(index: number): string { - return ZONE_COLORS[index % ZONE_COLORS.length] + return getZoneColor(index) } zoneFill(index: number): string { @@ -960,11 +951,6 @@ export class OcrTemplateEditorComponent implements OnInit, OnDestroy { }) } - getCustomFieldName(id: number): string { - const cf = this.customFields.find((f) => f.id === id) - return cf ? cf.name : `Field #${id}` - } - /** Value bound to the field select: a built-in id string or a custom-field id. */ zoneFieldValue(zone: OcrTemplateZone): ZoneFieldSelection { const target = zone.target || DEFAULT_OCR_ZONE_TARGET @@ -1069,16 +1055,6 @@ export class OcrTemplateEditorComponent implements OnInit, OnDestroy { ) } - getZoneTargetName(zone: OcrTemplateZone): string { - const target = zone.target || DEFAULT_OCR_ZONE_TARGET - if (target === OCR_ZONE_TARGET.CustomField) { - return zone.custom_field - ? this.getCustomFieldName(zone.custom_field) - : $localize`(no field)` - } - return this.builtinTargets.find((t) => t.id === target)?.name ?? target - } - getDocumentTypeName(id: number): string { const dt = this.documentTypes.find((d) => d.id === id) return dt ? dt.name : `Type #${id}` diff --git a/src-ui/src/app/components/manage/ocr-templates/ocr-template-editor/zone-geometry.ts b/src-ui/src/app/components/manage/ocr-templates/ocr-template-editor/zone-geometry.ts index 489dd58ba..8d6ff220b 100644 --- a/src-ui/src/app/components/manage/ocr-templates/ocr-template-editor/zone-geometry.ts +++ b/src-ui/src/app/components/manage/ocr-templates/ocr-template-editor/zone-geometry.ts @@ -36,6 +36,22 @@ export type ResizeHandle = 'n' | 's' | 'e' | 'w' | 'ne' | 'nw' | 'se' | 'sw' export const HANDLE_SIZE = 8 export const MIN_ZONE_SIZE = 10 +const ZONE_COLORS = [ + '#4f8ff7', + '#ff6b6b', + '#51cf66', + '#ffd43b', + '#cc5de8', + '#ff922b', + '#20c997', + '#e599f7', +] + +/** Outline color for a zone, shared by the preview overlay and the zone list. */ +export function getZoneColor(index: number): string { + return ZONE_COLORS[index % ZONE_COLORS.length] +} + export function getZonePage( zone: OcrTemplateZone, previewPage: number,