humainflow-web/src/app/shared/bias-annotations/bias-annotations.html

74 lines
3.5 KiB
HTML

@if (descriptor; as descriptor) {
<section class="bias-section" (pointerdown)="$event.stopPropagation()" (click)="$event.stopPropagation()">
<div class="bias-header">
<div>
<div class="bias-title">Bias annotations</div>
<div class="bias-counter">{{ annotations.length }}{{ descriptor.maxItems !== null ? ' / ' + descriptor.maxItems : '' }}</div>
</div>
@if (!readonly) {
<button type="button" class="bias-add" [disabled]="!canAdd" (click)="add($event)">Add bias annotation</button>
}
</div>
@if (listError(); as error) { <div class="bias-error">{{ error }}</div> }
@if (!annotations.length) {
<div class="bias-empty">No bias annotations.</div>
} @else {
<div class="bias-list">
@for (annotation of annotations; track annotation.id ?? $index; let index = $index) {
<article class="bias-card">
<div class="bias-badges">
<span class="bias-badge category">{{ optionLabel('category', annotation.category) }}</span>
<span class="bias-badge severity">{{ optionLabel('severity', annotation.severity) }}</span>
<span class="bias-badge status">{{ optionLabel('status', annotation.status) }}</span>
</div>
<div class="bias-issue">{{ annotation.issue }}</div>
@if (serverError(index); as error) { <div class="bias-error">{{ error }}</div> }
@for (field of fields; track field.key) {
@if (serverError(index, field.key); as error) { <div class="bias-error">{{ field.label }}: {{ error }}</div> }
}
@if (!readonly) {
<div class="bias-actions">
<button type="button" (click)="edit(index, $event)">Edit</button>
<button type="button" class="danger" (click)="remove(index, $event)">Remove</button>
</div>
}
</article>
}
</div>
}
</section>
@if (editorOpen) {
<div class="bias-modal-backdrop" (pointerdown)="$event.stopPropagation()" (click)="close($event)">
<form class="bias-modal" (pointerdown)="$event.stopPropagation()" (click)="$event.stopPropagation()" (submit)="save($event)">
<h3>{{ editingIndex === null ? 'Add' : 'Edit' }} bias annotation</h3>
<div class="bias-form">
@for (field of fields; track field.key) {
<label [class.invalid]="clientErrors[field.key]">
<span>{{ field.label }}{{ field.required ? ' *' : '' }}</span>
@if (field.options.length) {
<select [(ngModel)]="draft[field.key]" [name]="field.key">
<option value="">Select {{ field.label.toLowerCase() }}</option>
@for (option of field.options; track option.value) { <option [value]="option.value">{{ option.label }}</option> }
</select>
} @else if (field.widget === 'textarea' || (field.maxLength ?? 0) > 500) {
<textarea [(ngModel)]="draft[field.key]" [name]="field.key" [maxlength]="field.maxLength ?? null" [placeholder]="field.placeholder ?? ''" rows="5"></textarea>
} @else {
<input type="text" [(ngModel)]="draft[field.key]" [name]="field.key" [maxlength]="field.maxLength ?? null" [placeholder]="field.placeholder ?? ''" />
}
@if (optionDescription(field); as description) { <small>{{ description }}</small> }
@if (field.maxLength) { <small>{{ valueLength(field.key) }} / {{ field.maxLength }}</small> }
@if (clientErrors[field.key]; as error) { <em>{{ error }}</em> }
</label>
}
</div>
<div class="bias-modal-actions">
<button type="button" (click)="close($event)">Cancel</button>
<button type="submit" class="primary">Save</button>
</div>
</form>
</div>
}
}