|
|
|
@ -7,11 +7,11 @@ import { |
|
|
|
ElementRef, |
|
|
|
Input, |
|
|
|
OnChanges, |
|
|
|
OnDestroy, |
|
|
|
OnInit, |
|
|
|
signal, |
|
|
|
ViewChild |
|
|
|
viewChild |
|
|
|
} from '@angular/core'; |
|
|
|
import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; |
|
|
|
import { |
|
|
|
ControlValueAccessor, |
|
|
|
FormControl, |
|
|
|
@ -30,7 +30,9 @@ import { IonIcon } from '@ionic/angular/standalone'; |
|
|
|
import { Tag } from '@prisma/client'; |
|
|
|
import { addIcons } from 'ionicons'; |
|
|
|
import { addCircleOutline, closeOutline } from 'ionicons/icons'; |
|
|
|
import { BehaviorSubject, Subject, takeUntil } from 'rxjs'; |
|
|
|
import { BehaviorSubject, Subject } from 'rxjs'; |
|
|
|
|
|
|
|
import { SelectedTag } from './interfaces/interfaces'; |
|
|
|
|
|
|
|
@Component({ |
|
|
|
changeDetection: ChangeDetectionStrategy.OnPush, |
|
|
|
@ -57,27 +59,28 @@ import { BehaviorSubject, Subject, takeUntil } from 'rxjs'; |
|
|
|
templateUrl: 'tags-selector.component.html' |
|
|
|
}) |
|
|
|
export class GfTagsSelectorComponent |
|
|
|
implements ControlValueAccessor, OnChanges, OnDestroy, OnInit |
|
|
|
implements ControlValueAccessor, OnChanges, OnInit |
|
|
|
{ |
|
|
|
@Input() hasPermissionToCreateTag = false; |
|
|
|
@Input() readonly = false; |
|
|
|
@Input() tags: Tag[]; |
|
|
|
@Input() tagsAvailable: Tag[]; |
|
|
|
|
|
|
|
@ViewChild('tagInput') tagInput: ElementRef<HTMLInputElement>; |
|
|
|
@Input() tags: SelectedTag[]; |
|
|
|
@Input() tagsAvailable: SelectedTag[]; |
|
|
|
|
|
|
|
public filteredOptions: Subject<Tag[]> = new BehaviorSubject([]); |
|
|
|
public readonly filteredOptions: Subject<SelectedTag[]> = new BehaviorSubject( |
|
|
|
[] |
|
|
|
); |
|
|
|
public readonly separatorKeysCodes: number[] = [COMMA, ENTER]; |
|
|
|
public readonly tagInputControl = new FormControl(''); |
|
|
|
public readonly tagsSelected = signal<Tag[]>([]); |
|
|
|
public readonly tagsSelected = signal<SelectedTag[]>([]); |
|
|
|
|
|
|
|
private unsubscribeSubject = new Subject<void>(); |
|
|
|
private readonly tagInput = |
|
|
|
viewChild.required<ElementRef<HTMLInputElement>>('tagInput'); |
|
|
|
|
|
|
|
public constructor() { |
|
|
|
this.tagInputControl.valueChanges |
|
|
|
.pipe(takeUntil(this.unsubscribeSubject)) |
|
|
|
.pipe(takeUntilDestroyed()) |
|
|
|
.subscribe((value) => { |
|
|
|
this.filteredOptions.next(this.filterTags(value)); |
|
|
|
this.filteredOptions.next(this.filterTags(value ?? '')); |
|
|
|
}); |
|
|
|
|
|
|
|
addIcons({ addCircleOutline, closeOutline }); |
|
|
|
@ -106,6 +109,7 @@ export class GfTagsSelectorComponent |
|
|
|
}; |
|
|
|
} |
|
|
|
|
|
|
|
if (tag) { |
|
|
|
this.tagsSelected.update((tags) => { |
|
|
|
return [...(tags ?? []), tag]; |
|
|
|
}); |
|
|
|
@ -113,8 +117,10 @@ export class GfTagsSelectorComponent |
|
|
|
const newTags = this.tagsSelected(); |
|
|
|
this.onChange(newTags); |
|
|
|
this.onTouched(); |
|
|
|
this.tagInput.nativeElement.value = ''; |
|
|
|
this.tagInputControl.setValue(undefined); |
|
|
|
} |
|
|
|
|
|
|
|
this.tagInput().nativeElement.value = ''; |
|
|
|
this.tagInputControl.setValue(null); |
|
|
|
} |
|
|
|
|
|
|
|
public onRemoveTag(tag: Tag) { |
|
|
|
@ -130,7 +136,7 @@ export class GfTagsSelectorComponent |
|
|
|
this.updateFilters(); |
|
|
|
} |
|
|
|
|
|
|
|
public registerOnChange(fn: (value: Tag[]) => void) { |
|
|
|
public registerOnChange(fn: (value: SelectedTag[]) => void) { |
|
|
|
this.onChange = fn; |
|
|
|
} |
|
|
|
|
|
|
|
@ -146,17 +152,12 @@ export class GfTagsSelectorComponent |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
public writeValue(value: Tag[]) { |
|
|
|
public writeValue(value: SelectedTag[]) { |
|
|
|
this.tagsSelected.set(value || []); |
|
|
|
this.updateFilters(); |
|
|
|
} |
|
|
|
|
|
|
|
public ngOnDestroy() { |
|
|
|
this.unsubscribeSubject.next(); |
|
|
|
this.unsubscribeSubject.complete(); |
|
|
|
} |
|
|
|
|
|
|
|
private filterTags(query: string = ''): Tag[] { |
|
|
|
private filterTags(query: string = ''): SelectedTag[] { |
|
|
|
const tags = this.tagsSelected() ?? []; |
|
|
|
const tagIds = tags.map(({ id }) => { |
|
|
|
return id; |
|
|
|
@ -170,7 +171,7 @@ export class GfTagsSelectorComponent |
|
|
|
} |
|
|
|
|
|
|
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
|
|
private onChange = (_value: Tag[]): void => { |
|
|
|
private onChange = (_value: SelectedTag[]): void => { |
|
|
|
// ControlValueAccessor onChange callback
|
|
|
|
}; |
|
|
|
|
|
|
|
|