Skip to content

Commit d69a868

Browse files
committed
use signal
1 parent 736678c commit d69a868

File tree

2 files changed

+53
-32
lines changed

2 files changed

+53
-32
lines changed

projects/fusio-sdk/src/lib/component/form/autocomplete/form-autocomplete.component.html

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,22 @@
22
<div class="input-group">
33
<input
44
type="text"
5-
[id]="name"
6-
[name]="name"
7-
[(ngModel)]="selected"
5+
[id]="name()"
6+
[name]="name()"
7+
[ngModel]="selected()"
88
[ngbTypeahead]="objectSearch"
99
(focus)="focus$.next($any($event).target.value)"
1010
[inputFormatter]="objectFormatter"
1111
[resultFormatter]="objectFormatter"
1212
[editable]="false"
13-
(ngModelChange)="changeValue()"
14-
[disabled]="disabled"
13+
(ngModelChange)="selected.set($event);changeValue()"
14+
[disabled]="disabled()"
1515
(keydown.enter)="enter.emit()"
1616
placeholder="Type to search ..."
1717
class="form-control"
1818
/>
19-
@if (searching) {
20-
<button class="btn btn-outline-secondary" type="button" disabled>
19+
@if (searching()) {
20+
<button class="btn btn-outline-secondary" [ngClass]="{'btn-outline-danger': searchFailed()}" type="button" disabled>
2121
<span class="spinner-border spinner-border-sm" aria-hidden="true"></span>
2222
<span class="visually-hidden" role="status">Loading...</span>
2323
</button>

projects/fusio-sdk/src/lib/component/form/autocomplete/form-autocomplete.component.ts

Lines changed: 46 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,52 @@
1-
import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core';
1+
import {Component, effect, EventEmitter, input, Input, Output, signal} from '@angular/core';
22
import {IdAndName, Service} from "../../../abstract/service";
3-
import {catchError, debounceTime, distinctUntilChanged, map, merge, Observable, of, OperatorFunction, Subject, switchMap, tap} from "rxjs";
3+
import {
4+
catchError,
5+
debounceTime,
6+
distinctUntilChanged,
7+
map,
8+
merge,
9+
Observable,
10+
of,
11+
OperatorFunction,
12+
Subject,
13+
switchMap,
14+
tap
15+
} from "rxjs";
416
import {fromPromise} from "rxjs/internal/observable/innerFrom";
517
import {FormsModule} from "@angular/forms";
618
import {NgbTypeahead} from "@ng-bootstrap/ng-bootstrap";
19+
import {NgClass} from "@angular/common";
720

821
@Component({
922
selector: 'fusio-form-autocomplete',
1023
templateUrl: './form-autocomplete.component.html',
1124
imports: [
1225
FormsModule,
13-
NgbTypeahead
26+
NgbTypeahead,
27+
NgClass
1428
],
1529
styleUrls: ['./form-autocomplete.component.css']
1630
})
17-
export class FormAutocompleteComponent implements OnInit {
31+
export class FormAutocompleteComponent {
1832

19-
@Input() name!: string;
20-
@Input() disabled: boolean = false;
21-
@Input() data?: string|number = undefined;
2233
@Input() service!: Service<any>;
23-
@Input() useTilde: boolean = false;
24-
@Input() useId: boolean = false;
2534
@Output() dataChange = new EventEmitter<string>();
2635
@Output() dataChangeId = new EventEmitter<number>();
2736
@Output() enter = new EventEmitter<void>();
2837

2938
focus$ = new Subject<string>();
3039

31-
searching = false;
32-
searchFailed = false;
40+
name = input.required<string>();
41+
disabled = input<boolean>(false);
42+
data = input<string|number|undefined>();
43+
useTilde = input<boolean>(false);
44+
useId = input<boolean>(false);
3345

34-
selected?: IdAndName<any>
46+
searching = signal<boolean>(false);
47+
searchFailed = signal<boolean>(false);
48+
49+
selected = signal<IdAndName<any>|undefined>(undefined)
3550

3651
objectFormatter = (object: IdAndName<any>): string => {
3752
return object.name;
@@ -42,41 +57,47 @@ export class FormAutocompleteComponent implements OnInit {
4257
const inputFocus$ = this.focus$;
4358

4459
return merge(debouncedText$, inputFocus$).pipe(
45-
tap(() => (this.searching = true)),
60+
tap(() => (this.searching.set(true))),
4661
switchMap((term) =>
4762
fromPromise(this.service.getAllWithIdAndName([0, 16, term])).pipe(
4863
map((response) => {
4964
return response.entry ? response.entry : [];
5065
}),
51-
tap(() => (this.searchFailed = false)),
66+
tap(() => (this.searchFailed.set(false))),
5267
catchError(() => {
53-
this.searchFailed = true;
68+
this.searchFailed.set(true);
5469
return of([]);
5570
}),
5671
),
5772
),
58-
tap(() => (this.searching = false)),
73+
tap(() => (this.searching.set(false))),
5974
);
6075
}
6176

62-
async ngOnInit(): Promise<void> {
63-
if (this.data) {
64-
this.selected = await this.service.getWithIdAndName((this.useTilde ? '~' : '') + this.data);
65-
}
77+
constructor() {
78+
effect(async () => {
79+
const data = this.data();
80+
if (data) {
81+
this.selected.set(await this.service.getWithIdAndName((this.useTilde() ? '~' : '') + data));
82+
}
83+
});
6684
}
6785

6886
changeValue() {
69-
if (this.disabled || !this.selected) {
87+
const selected = this.selected();
88+
if (this.disabled() || !selected) {
7089
return;
7190
}
7291

7392
if (this.dataChange.observed) {
74-
if (this.selected.name) {
75-
this.dataChange.emit(this.useId ? this.selected.id : this.selected.name);
93+
if (this.useId() && selected.id) {
94+
this.dataChange.emit(selected.id);
95+
} else if (selected.name) {
96+
this.dataChange.emit(selected.name);
7697
}
7798
} else if (this.dataChangeId.observed) {
78-
if (this.selected.id) {
79-
this.dataChangeId.emit(parseInt(this.selected.id));
99+
if (selected.id) {
100+
this.dataChangeId.emit(parseInt(selected.id));
80101
}
81102
}
82103
}

0 commit comments

Comments
 (0)