Skip to content

Commit 9df972a

Browse files
Deforestation
1 parent af84cae commit 9df972a

1 file changed

Lines changed: 51 additions & 48 deletions

File tree

frontend/src/app/annotate/annotation-input/problem-details/problem-labels/manage-labels-modal/manage-labels-modal.component.ts

Lines changed: 51 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@ import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
55
import { ProblemService } from '@/services/problem.service';
66
import { toSignal } from '@angular/core/rxjs-interop';
77
import { AuthService } from '@/services/auth.service';
8-
import { map, combineLatest, Subject, startWith, defer, Observable } from 'rxjs';
8+
import { map, combineLatest, Subject, startWith, defer, Observable, filter } from 'rxjs';
99
import { AsyncPipe } from '@angular/common';
1010
import { formatDate } from '@/util';
11-
import { LabelAnnotation } from '@/types';
11+
import { Label, LabelAnnotation } from '@/types';
1212

1313
type SelectedLabelsForm = FormGroup<{
1414
problemId: FormControl<number>;
@@ -47,55 +47,20 @@ export class ManageLabelsModalComponent implements OnInit {
4747
startWith(this.form.controls.selectedLabelIds.value),
4848
));
4949

50-
/** Combines selected IDs with existing annotations and all labels to show what's selected */
51-
public shownLabels$: Observable<LabelAnnotation[]> = combineLatest([
52-
this.allLabels$,
50+
public allLabelsAndSelectedIds = combineLatest([
51+
this.allLabels$.pipe(filter(labels => labels.length > 0)),
5352
this.selectedLabelIds$
54-
]).pipe(
55-
map(([allLabels, selectedIds]) => {
56-
if (!allLabels) {
57-
return [];
58-
}
59-
// Show existing annotations that are still selected, plus new ones
60-
return selectedIds.map(labelId => {
61-
const existing = this.currentAnnotations.find(a => a.label.id === labelId);
62-
if (existing) {
63-
return existing;
64-
}
65-
// Create a simple display object for newly selected labels
66-
const label = allLabels.find(l => l.id === labelId);
67-
if (!label) {
68-
return null;
69-
}
70-
71-
const newAnnotation: LabelAnnotation = {
72-
id: null,
73-
label,
74-
createdAt: new Date().toISOString(),
75-
createdBy: this.currentUserName() ?? $localize`Unknown user`,
76-
attachedByCurrentUser: true,
77-
session: null,
78-
removedAt: null,
79-
removedBy: null,
80-
notes: '',
81-
removable: true,
82-
83-
};
84-
return newAnnotation;
85-
}).filter((a) => a !== null);
86-
})
53+
]);
54+
55+
/**
56+
* Turns selected label IDs into objects that are used in the template.
57+
*/
58+
public shownLabels$: Observable<LabelAnnotation[]> = this.allLabelsAndSelectedIds.pipe(
59+
map(([allLabels, selectedIds]) => this.convertSelectedIdsToAnnotations(selectedIds, allLabels)),
8760
);
8861

89-
public availableLabels$ = combineLatest([
90-
this.allLabels$,
91-
this.selectedLabelIds$
92-
]).pipe(
93-
map(([allLabels, selectedIds]) => {
94-
if (!allLabels) {
95-
return [];
96-
}
97-
return allLabels.filter(label => !selectedIds.includes(label.id));
98-
})
62+
public availableLabels$ = this.allLabelsAndSelectedIds.pipe(
63+
map(([allLabels, selectedIds]) => allLabels.filter(label => !selectedIds.includes(label.id))),
9964
);
10065

10166
public loadingLabels$ = this.availableLabels$.pipe(
@@ -146,4 +111,42 @@ export class ManageLabelsModalComponent implements OnInit {
146111
private currentUserName = toSignal(
147112
this.authService.currentUser$.pipe(map((user) => user?.username))
148113
);
114+
115+
private convertSelectedIdsToAnnotations(selectedIds: number[], allLabels: Label[]): LabelAnnotation[] {
116+
const existingAnnotationMap = new Map(
117+
this.currentAnnotations.map(a => [a.label.id, a])
118+
);
119+
const allLabelsMap = new Map(allLabels.map(l => [l.id, l]));
120+
const currentUser = this.currentUserName() ?? $localize`Unknown user`;
121+
122+
return selectedIds.map(labelId => {
123+
// Try to find existing annotation first
124+
const existing = existingAnnotationMap.get(labelId);
125+
if (existing) {
126+
return existing;
127+
}
128+
129+
return this.createAnnotationForId(labelId, allLabelsMap, currentUser);
130+
}).filter(annotation => annotation !== null);
131+
}
132+
133+
private createAnnotationForId(labelId: number, allLabels: Map<number, Label>, currentUser: string): LabelAnnotation | null {
134+
const label = allLabels.get(labelId);
135+
if (!label) {
136+
return null;
137+
}
138+
139+
return {
140+
id: null,
141+
label,
142+
createdAt: new Date().toISOString(),
143+
createdBy: currentUser,
144+
attachedByCurrentUser: true,
145+
session: null,
146+
removedAt: null,
147+
removedBy: null,
148+
notes: '',
149+
removable: true,
150+
} as LabelAnnotation;
151+
}
149152
}

0 commit comments

Comments
 (0)