Skip to content

Commit 930441c

Browse files
authored
refacto trainrun filter service for label uniqueness (SchweizerischeBundesbahnen#212)
* refacto trainrun filter service for label uniqueness * fix error if trainrun is deleted * refactor node filter label uniqueness * fix bug for note label initialization + refactor label uniqueness * remove console log for test
1 parent 5173657 commit 930441c

File tree

6 files changed

+111
-52
lines changed

6 files changed

+111
-52
lines changed

src/app/services/data/node.service.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -982,17 +982,17 @@ export class NodeService implements OnDestroy {
982982

983983
changeLabels(nodeId: number, labels: string[]) {
984984
const node = this.getNodeFromId(nodeId);
985-
const labelIds: number[] = [];
986-
labels.forEach((label) => {
987-
labelIds.push(
988-
this.labelService.getOrCreateLabel(label, LabelRef.Node).getId(),
989-
);
990-
});
991-
const deletetLabelIds = this.labelService.clearLabel(
985+
986+
// ensure uniqueness of input labels
987+
const uniqueLabels = Array.from(new Set(labels));
988+
const labelIds = uniqueLabels.map(label =>
989+
this.labelService.getOrCreateLabel(label, LabelRef.Node).getId()
990+
);
991+
const deletedLabelIds = this.labelService.clearLabel(
992992
this.findClearedLabel(node, labelIds),
993993
this.makeLabelIDCounterMap(this.getNodes()),
994994
);
995-
this.filterService.clearDeletetFilterNodeLabels(deletetLabelIds);
995+
this.filterService.clearDeletetFilterNodeLabels(deletedLabelIds);
996996
node.setLabelIds(labelIds);
997997
this.nodesUpdated();
998998
}

src/app/services/data/note.service.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -188,17 +188,17 @@ export class NoteService {
188188

189189
setLabels(noteId: number, labels: string[]) {
190190
const note = this.getNoteFromId(noteId);
191-
const labelIds: number[] = [];
192-
labels.forEach((label) => {
193-
labelIds.push(
194-
this.labelService.getOrCreateLabel(label, LabelRef.Note).getId(),
195-
);
196-
});
197-
const deletetLabelIds = this.labelService.clearLabel(
191+
192+
// ensure uniqueness of input labels
193+
const uniqueLabels = Array.from(new Set(labels));
194+
const labelIds = uniqueLabels.map(label =>
195+
this.labelService.getOrCreateLabel(label, LabelRef.Note).getId()
196+
);
197+
const deletedLabelIds = this.labelService.clearLabel(
198198
this.findClearedLabel(note, labelIds),
199199
this.makeLabelIDCounterMap(this.getNotes()),
200200
);
201-
this.filterService.clearDeletetFilterNoteLabels(deletetLabelIds);
201+
this.filterService.clearDeletetFilterNoteLabels(deletedLabelIds);
202202
note.setLabelIds(labelIds);
203203
this.notesUpdated();
204204
}

src/app/services/data/trainrun.service.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -529,17 +529,17 @@ export class TrainrunService {
529529

530530
setLabels(trainrunId: number, labels: string[]) {
531531
const trainrun = this.getTrainrunFromId(trainrunId);
532-
const labelIds: number[] = [];
533-
labels.forEach((label) => {
534-
labelIds.push(
535-
this.labelService.getOrCreateLabel(label, LabelRef.Trainrun).getId(),
536-
);
537-
});
538-
const deletetLabelIds = this.labelService.clearLabel(
532+
533+
// ensure uniqueness of input labels
534+
const uniqueLabels = Array.from(new Set(labels));
535+
const labelIds = uniqueLabels.map(label =>
536+
this.labelService.getOrCreateLabel(label, LabelRef.Trainrun).getId()
537+
);
538+
const deletedLabelIds = this.labelService.clearLabel(
539539
this.findClearedLabel(trainrun, labelIds),
540540
this.makeLabelIDCounterMap(this.getTrainruns()),
541541
);
542-
this.filterService.clearDeletetFilterTrainrunLabels(deletetLabelIds);
542+
this.filterService.clearDeletetFilterTrainrunLabels(deletedLabelIds);
543543
trainrun.setLabelIds(labelIds);
544544
this.trainrunsUpdated();
545545
}

src/app/view/dialogs/note-dialog/note-filter-tab/note-filter-tab.component.ts

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,11 @@ export class NoteFilterTabComponent implements OnInit, OnDestroy {
3030

3131
public note: Note;
3232
public noteLabels: string[];
33+
private initialNoteLabels: string[];
3334
noteLabelsAutoCompleteOptions: string[] = [];
3435
readonly separatorKeysCodes = [ENTER, COMMA];
3536
private destroyed = new Subject<void>();
37+
private isLabelBeingEdited = false;
3638

3739
constructor(
3840
public dataService: DataService,
@@ -47,6 +49,11 @@ export class NoteFilterTabComponent implements OnInit, OnDestroy {
4749
this.noteService.notes.pipe(takeUntil(this.destroyed)).subscribe(() => {
4850
this.updateNoteLabelsAutoCompleteOptions();
4951
});
52+
this.noteService.notes
53+
.pipe(takeUntil(this.destroyed))
54+
.subscribe(() => {
55+
this.initializeWithCurrentNote();
56+
});
5057
this.updateNoteLabelsAutoCompleteOptions();
5158
}
5259

@@ -64,7 +71,9 @@ export class NoteFilterTabComponent implements OnInit, OnDestroy {
6471
this.noteLabels = this.noteLabels.filter(
6572
(labels) => labels !== valueDelete,
6673
);
67-
this.noteService.setLabels(this.note.getId(), this.noteLabels);
74+
this.isLabelBeingEdited = true;
75+
this.checkAndSetLabels();
76+
this.isLabelBeingEdited = false;
6877
}
6978

7079
add(chipInputEvent: SbbChipInputEvent): void {
@@ -73,11 +82,15 @@ export class NoteFilterTabComponent implements OnInit, OnDestroy {
7382
return;
7483
}
7584
this.noteLabels.push(value);
76-
this.noteService.setLabels(this.note.getId(), this.noteLabels);
85+
this.isLabelBeingEdited = true;
86+
this.checkAndSetLabels();
87+
this.isLabelBeingEdited = false;
7788
chipInputEvent.chipInput!.clear();
7889
}
7990

8091
onLabelsFocusout() {
92+
if (this.isLabelBeingEdited) return;
93+
8194
const keyboardEvent = new KeyboardEvent("keydown", {
8295
code: "Enter",
8396
key: "Enter",
@@ -87,6 +100,7 @@ export class NoteFilterTabComponent implements OnInit, OnDestroy {
87100
bubbles: true,
88101
});
89102
document.getElementById("noteLabelsInput").dispatchEvent(keyboardEvent);
103+
this.checkAndSetLabels();
90104
}
91105

92106
onDeleteNote(): void {
@@ -104,16 +118,32 @@ export class NoteFilterTabComponent implements OnInit, OnDestroy {
104118
}
105119

106120
private initializeWithCurrentNote() {
121+
if (this.note === null) return;
107122
this.note = this.noteService.getNoteFromId(
108123
this.noteDialogParameter.noteFormComponentModel.id,
109124
);
110125
this.noteLabels = this.labelService.getTextLabelsFromIds(
111126
this.note.getLabelIds(),
112127
);
128+
this.initialNoteLabels = [...this.noteLabels]; // initialize labels
113129
}
114130

115131
private updateNoteLabelsAutoCompleteOptions() {
116132
this.noteLabelsAutoCompleteOptions = this.getAutoCompleteLabels();
117133
this.cd.detectChanges();
118134
}
135+
136+
// set labels only if any of it has changed
137+
private checkAndSetLabels() {
138+
if (
139+
this.noteLabels.length !== this.initialNoteLabels.length ||
140+
!this.noteLabels.every((label, index) => label === this.initialNoteLabels[index])
141+
) {
142+
this.noteService.setLabels(
143+
this.note.getId(),
144+
this.noteLabels
145+
);
146+
this.initialNoteLabels = [...this.noteLabels];
147+
}
148+
}
119149
}

src/app/view/dialogs/trainrun-and-section-dialog/trainrun-filter-tab/trainrun-filter-tab.component.ts

Lines changed: 28 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,11 @@ export class TrainrunFilterTabComponent implements OnInit, OnDestroy {
3030

3131
public selectedTrainrun: Trainrun;
3232
public trainrunLabels: string[];
33+
private initialTrainrunLabels: string[];
3334
trainrunLabelsAutoCompleteOptions: string[] = [];
3435
readonly separatorKeysCodes = [ENTER, COMMA];
3536
private destroyed = new Subject<void>();
37+
private isLabelBeingEdited = false;
3638

3739
constructor(
3840
public dataService: DataService,
@@ -76,23 +78,20 @@ export class TrainrunFilterTabComponent implements OnInit, OnDestroy {
7678
this.trainrunLabels = this.trainrunLabels.filter(
7779
(labels) => labels !== valueDelete,
7880
);
79-
this.trainrunService.setLabels(
80-
this.selectedTrainrun.getId(),
81-
this.trainrunLabels,
82-
);
81+
this.isLabelBeingEdited = true;
82+
this.checkAndSetLabels();
83+
this.isLabelBeingEdited = false;
8384
}
8485

8586
add(inputEvent: SbbChipInputEvent): void {
8687
const value = (inputEvent.value || "").trim();
8788
if (!value) {
8889
return;
8990
}
90-
console.log("add", value);
9191
this.trainrunLabels.push(value);
92-
this.trainrunService.setLabels(
93-
this.selectedTrainrun.getId(),
94-
this.trainrunLabels,
95-
);
92+
this.isLabelBeingEdited = true;
93+
this.checkAndSetLabels();
94+
this.isLabelBeingEdited = false;
9695
inputEvent.chipInput!.clear();
9796
}
9897

@@ -121,6 +120,8 @@ export class TrainrunFilterTabComponent implements OnInit, OnDestroy {
121120
}
122121

123122
onLabelsFocusout() {
123+
if (this.isLabelBeingEdited) return;
124+
124125
const keyboardEvent = new KeyboardEvent("keydown", {
125126
code: "Enter",
126127
key: "Enter",
@@ -130,10 +131,7 @@ export class TrainrunFilterTabComponent implements OnInit, OnDestroy {
130131
bubbles: true,
131132
});
132133
document.getElementById("trainrunLabelsInput").dispatchEvent(keyboardEvent);
133-
this.trainrunService.setLabels(
134-
this.selectedTrainrun.getId(),
135-
this.trainrunLabels,
136-
);
134+
this.checkAndSetLabels();
137135
}
138136

139137
getAutoCompleteLabels(): string[] {
@@ -145,13 +143,29 @@ export class TrainrunFilterTabComponent implements OnInit, OnDestroy {
145143

146144
private initializeWithCurrentSelectedTrainrun() {
147145
this.selectedTrainrun = this.trainrunService.getSelectedTrainrun();
146+
if (this.selectedTrainrun === null) return;
148147
this.trainrunLabels = this.labelService.getTextLabelsFromIds(
149148
this.selectedTrainrun.getLabelIds(),
150149
);
150+
this.initialTrainrunLabels = [...this.trainrunLabels]; // initialize labels
151151
}
152152

153153
private updateTrainrunLabelsAutoCompleteOptions() {
154154
this.trainrunLabelsAutoCompleteOptions = this.getAutoCompleteLabels();
155155
this.cd.detectChanges();
156156
}
157-
}
157+
158+
// set labels only if any of it has changed
159+
private checkAndSetLabels() {
160+
if (
161+
this.trainrunLabels.length !== this.initialTrainrunLabels.length ||
162+
!this.trainrunLabels.every((label, index) => label === this.initialTrainrunLabels[index])
163+
) {
164+
this.trainrunService.setLabels(
165+
this.selectedTrainrun.getId(),
166+
this.trainrunLabels
167+
);
168+
this.initialTrainrunLabels = [...this.trainrunLabels];
169+
}
170+
}
171+
}

src/app/view/editor-side-view/editor-node-detail-view/editor-node-detail-view.component.ts

Lines changed: 27 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -54,10 +54,13 @@ export class EditorNodeDetailViewComponent implements OnInit, OnDestroy {
5454
labels: [],
5555
};
5656

57+
private initialNodeLabels: string[];
58+
5759
readonly separatorKeysCodes = [ENTER, COMMA];
5860
nodeLabelsAutoCompleteOptions: string[] = [];
5961

6062
private destroyed = new Subject<void>();
63+
private isLabelBeingEdited = false;
6164

6265
constructor(
6366
private uiInteractionService: UiInteractionService,
@@ -117,10 +120,9 @@ export class EditorNodeDetailViewComponent implements OnInit, OnDestroy {
117120
return;
118121
}
119122
this.nodeProperties.labels.push(value);
120-
this.nodeService.changeLabels(
121-
this.nodeProperties.nodeId,
122-
this.nodeProperties.labels,
123-
);
123+
this.isLabelBeingEdited = true;
124+
this.checkAndSetLabels();
125+
this.isLabelBeingEdited = false;
124126
chipInputEvent.chipInput!.clear();
125127
}
126128

@@ -133,13 +135,14 @@ export class EditorNodeDetailViewComponent implements OnInit, OnDestroy {
133135
this.nodeProperties.labels = this.nodeProperties.labels.filter(
134136
(labels) => labels !== valueDelete,
135137
);
136-
this.nodeService.changeLabels(
137-
this.nodeProperties.nodeId,
138-
this.nodeProperties.labels,
139-
);
138+
this.isLabelBeingEdited = true;
139+
this.checkAndSetLabels();
140+
this.isLabelBeingEdited = false;
140141
}
141142

142143
onLabelsFocusout() {
144+
if (this.isLabelBeingEdited) return;
145+
143146
const keyboardEvent = new KeyboardEvent("keydown", {
144147
code: "Enter",
145148
key: "Enter",
@@ -149,10 +152,7 @@ export class EditorNodeDetailViewComponent implements OnInit, OnDestroy {
149152
bubbles: true,
150153
});
151154
document.getElementById("nodeLabelsInput").dispatchEvent(keyboardEvent);
152-
this.nodeService.changeLabels(
153-
this.nodeProperties.nodeId,
154-
this.nodeProperties.labels,
155-
);
155+
this.checkAndSetLabels();
156156
}
157157

158158
onCapacityChanged() {
@@ -261,6 +261,21 @@ export class EditorNodeDetailViewComponent implements OnInit, OnDestroy {
261261
selectedNode.getLabelIds(),
262262
),
263263
};
264+
this.initialNodeLabels = [...this.nodeProperties.labels]; // initialize labels
265+
}
266+
}
267+
268+
// set labels only if any of it has changed
269+
private checkAndSetLabels() {
270+
if (
271+
this.nodeProperties.labels.length !== this.initialNodeLabels.length ||
272+
!this.nodeProperties.labels.every((label, index) => label === this.initialNodeLabels[index])
273+
) {
274+
this.nodeService.changeLabels(
275+
this.nodeProperties.nodeId,
276+
this.nodeProperties.labels
277+
);
278+
this.initialNodeLabels = [...this.nodeProperties.labels];
264279
}
265280
}
266281
}

0 commit comments

Comments
 (0)