Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add post validation to cps-autocomplete component #404

Merged
merged 2 commits into from
Oct 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions projects/composition/src/app/api-data/cps-autocomplete.json
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,14 @@
"default": "500",
"description": "Debounce time for inputChanged event."
},
{
"name": "validating",
"optional": false,
"readonly": false,
"type": "boolean",
"default": "false",
"description": "Determines whether the component is currently validating the selected value asynchronously."
},
{
"name": "_value",
"optional": false,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,21 @@
prefixIcon="search"
appearance="borderless">
</cps-autocomplete>

<cps-autocomplete
label="Autocomplete with async validation"
[options]="options"
optionLabel="name"
optionInfo="info"
placeholder="Select a city"
[clearable]="true"
[(ngModel)]="selectedOption"
[ngModelOptions]="{ standalone: true }"
[validating]="validating"
korel-san marked this conversation as resolved.
Show resolved Hide resolved
(valueChanged)="onOptionSelected($event)"
[externalError]="externalError"
hint="This autocomplete simulates async validation upon selection.">
</cps-autocomplete>
</div>
</form>
</app-component-docs-viewer>
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,15 @@
import {
FormsModule,
ReactiveFormsModule,
UntypedFormBuilder,
UntypedFormGroup,
FormBuilder,
FormGroup,
Validators
} from '@angular/forms';
import { CpsAutocompleteComponent } from 'cps-ui-kit';
import { ComponentDocsViewerComponent } from '../../components/component-docs-viewer/component-docs-viewer.component';
import ComponentData from '../../api-data/cps-autocomplete.json';
import {
Observable,
Subject,
catchError,
delay,
finalize,
of,
switchMap
} from 'rxjs';
import { Observable, Subject, of, delay } from 'rxjs';
import { switchMap, tap } from 'rxjs/operators';
import { CommonModule } from '@angular/common';

@Component({
Expand Down Expand Up @@ -58,25 +51,30 @@
{ title: 'Tesla', val: 'TSLA', ticker: 'TSLA' }
];

form!: UntypedFormGroup;
form!: FormGroup;
syncVal: any = [];

Check warning on line 55 in projects/composition/src/app/pages/autocomplete-page/autocomplete-page.component.ts

View workflow job for this annotation

GitHub Actions / test

Unexpected any. Specify a different type
componentData = ComponentData;

isSingleLoading = false;
isMultiLoading = false;
externalError = '';

private _singleFilterOptionSubject$ = new Subject<string>();
singleOptionsObservable$?: Observable<any>;

Check warning on line 63 in projects/composition/src/app/pages/autocomplete-page/autocomplete-page.component.ts

View workflow job for this annotation

GitHub Actions / test

Unexpected any. Specify a different type

private _multiFilterOptionSubject$ = new Subject<string>();
multiOptionsObservable$?: Observable<any>;

Check warning on line 66 in projects/composition/src/app/pages/autocomplete-page/autocomplete-page.component.ts

View workflow job for this annotation

GitHub Actions / test

Unexpected any. Specify a different type

// New properties for the validating example
validating = false;
selectedOption: any = null;

Check warning on line 70 in projects/composition/src/app/pages/autocomplete-page/autocomplete-page.component.ts

View workflow job for this annotation

GitHub Actions / test

Unexpected any. Specify a different type

get availableOptionInfo() {
return this.options.map((option) => option.name).join(', ');
}

// eslint-disable-next-line no-useless-constructor
constructor(private _formBuilder: UntypedFormBuilder) {}
constructor(private _formBuilder: FormBuilder) {}

ngOnInit(): void {
this.form = this._formBuilder.group({
Expand Down Expand Up @@ -110,29 +108,49 @@
private _defineOptionsObservable(
subject$: Subject<string>,
single: boolean
): Observable<any> | undefined {

Check warning on line 111 in projects/composition/src/app/pages/autocomplete-page/autocomplete-page.component.ts

View workflow job for this annotation

GitHub Actions / test

Unexpected any. Specify a different type
return subject$.pipe(
switchMap((value) => {
if (single) this.isSingleLoading = true;
else this.isMultiLoading = true;
return this._getOptionsFromServer(value).pipe(
catchError((error) => {
console.error('Failed to retrieve options list', error);
return of([]);
}),
finalize(() => {
if (single) this.isSingleLoading = false;
else this.isMultiLoading = false;
// Handle errors and finalize loading state
tap({
complete: () => {
if (single) this.isSingleLoading = false;
else this.isMultiLoading = false;
}
})
);
})
);
}

private _getOptionsFromServer(val: string): Observable<any> {

Check warning on line 129 in projects/composition/src/app/pages/autocomplete-page/autocomplete-page.component.ts

View workflow job for this annotation

GitHub Actions / test

Unexpected any. Specify a different type
const filteredRes = this.options.filter((option) => {
return option.name?.toLowerCase()?.includes(val);
});
return of(filteredRes).pipe(delay(1000));
}

// Method to handle selection changes for async validation
onOptionSelected(option: any) {

Check warning on line 137 in projects/composition/src/app/pages/autocomplete-page/autocomplete-page.component.ts

View workflow job for this annotation

GitHub Actions / test

Unexpected any. Specify a different type
this.validating = true;
this.selectedOption = option;
this.externalError = '';
// Simulate async validation with a delay
of(option)
.pipe(
delay(3000) // Simulate a delay of 2 seconds
)
.subscribe({
next: () => {
this.validating = false;
},
error: () => {
// Handle errors and finalize validation state
this.externalError = 'Validation failed';
}
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@
</div>
</cps-menu>
<cps-progress-linear
*ngIf="loading"
*ngIf="loading || validating"
height="3"
radius="4"
opacity="0.3"
Expand All @@ -234,7 +234,7 @@
<div
*ngIf="(error || externalError) && !hideDetails"
class="cps-autocomplete-error">
{{ error }}
{{ error || externalError }}
</div>
</div>

Expand Down
Loading
Loading