74 lines
3.5 KiB
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>
|
|
}
|
|
}
|