mirror of
https://github.com/valitydev/dashboard.git
synced 2024-11-06 10:35:21 +00:00
FRONTENT-506. Wallet autocomplete (#431)
* wallet autocomplete * fix * fix with bug * dsh-autocomplete-input * fix * lint fix * package lock fix * fixes * more fixes * more more fixes * fixes * more fixes * remove validator * fixes
This commit is contained in:
parent
f57f68e51b
commit
8714939d3e
@ -5,10 +5,7 @@
|
||||
<mat-label>{{ t('depositID') }}</mat-label>
|
||||
<input aria-label="depositID" matInput type="text" formControlName="depositID" />
|
||||
</mat-form-field>
|
||||
<mat-form-field fxFlex>
|
||||
<mat-label>{{ t('walletID') }}</mat-label>
|
||||
<input aria-label="walletID" matInput type="text" formControlName="walletID" />
|
||||
</mat-form-field>
|
||||
<dsh-wallet-autocomplete-field fxFlex [control]="form?.controls?.walletID"></dsh-wallet-autocomplete-field>
|
||||
</div>
|
||||
<div fxLayout="row" fxLayoutAlign="space-between" fxLayoutGap="24px">
|
||||
<mat-form-field fxFlex>
|
||||
|
@ -6,10 +6,20 @@ import { MatFormFieldModule } from '@angular/material/form-field';
|
||||
import { MatInputModule } from '@angular/material/input';
|
||||
import { TranslocoModule } from '@ngneat/transloco';
|
||||
|
||||
import { WalletAutocompleteFieldModule } from '@dsh/app/shared/components/inputs/wallet-autocomplete-field';
|
||||
|
||||
import { MainFiltersComponent } from './main-filters.component';
|
||||
|
||||
@NgModule({
|
||||
imports: [CommonModule, MatFormFieldModule, MatInputModule, ReactiveFormsModule, FlexLayoutModule, TranslocoModule],
|
||||
imports: [
|
||||
CommonModule,
|
||||
MatFormFieldModule,
|
||||
MatInputModule,
|
||||
ReactiveFormsModule,
|
||||
FlexLayoutModule,
|
||||
TranslocoModule,
|
||||
WalletAutocompleteFieldModule,
|
||||
],
|
||||
declarations: [MainFiltersComponent],
|
||||
exports: [MainFiltersComponent],
|
||||
})
|
||||
|
@ -28,17 +28,10 @@
|
||||
t('createWebhook.eventTypes.destination')
|
||||
}}</mat-radio-button>
|
||||
</mat-radio-group>
|
||||
<mat-form-field *ngIf="(activeTopic$ | async) === 'WithdrawalsTopic'" fxFlex>
|
||||
<mat-label>{{ t('createWebhook.wallet') }}</mat-label>
|
||||
<mat-select formControlName="walletID">
|
||||
<mat-option *transloco="let c">
|
||||
{{ c('any') }}
|
||||
</mat-option>
|
||||
<mat-option *ngFor="let wallet of wallets$ | async" [value]="wallet.id">
|
||||
{{ wallet.name }}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
<dsh-wallet-autocomplete-field
|
||||
*ngIf="(activeTopic$ | async) === 'WithdrawalsTopic'"
|
||||
[control]="form?.controls?.walletID"
|
||||
></dsh-wallet-autocomplete-field>
|
||||
<mat-divider></mat-divider>
|
||||
<div fxLayout="column" fxLayoutGap="8px">
|
||||
<div class="dsh-title">{{ t('createWebhook.events') }}</div>
|
||||
|
@ -1,38 +1,32 @@
|
||||
import { Component, Input, OnInit } from '@angular/core';
|
||||
import { FormArray, FormBuilder, FormGroup } from '@angular/forms';
|
||||
import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy';
|
||||
import { BehaviorSubject } from 'rxjs';
|
||||
|
||||
import { WebhookScope } from '@dsh/api-codegen/wallet-api/swagger-codegen';
|
||||
import { IdentityService } from '@dsh/api/identity';
|
||||
import { WalletService } from '@dsh/api/wallet';
|
||||
import { oneMustBeSelected } from '@dsh/components/form-controls';
|
||||
|
||||
import { getEventsByTopic } from '../get-events-by-topic';
|
||||
|
||||
import TopicEnum = WebhookScope.TopicEnum;
|
||||
|
||||
@UntilDestroy()
|
||||
@Component({
|
||||
selector: 'dsh-create-webhook-form',
|
||||
templateUrl: 'create-webhook-form.component.html',
|
||||
})
|
||||
export class CreateWebhookFormComponent implements OnInit {
|
||||
@Input()
|
||||
form: FormGroup;
|
||||
|
||||
wallets$ = this.walletService.wallets$;
|
||||
@Input() form: FormGroup;
|
||||
|
||||
identities$ = this.identityService.identities$;
|
||||
|
||||
activeTopic$ = new BehaviorSubject<TopicEnum>('WithdrawalsTopic');
|
||||
|
||||
constructor(
|
||||
private walletService: WalletService,
|
||||
private identityService: IdentityService,
|
||||
private fb: FormBuilder
|
||||
) {}
|
||||
constructor(private identityService: IdentityService, private fb: FormBuilder) {}
|
||||
|
||||
ngOnInit() {
|
||||
this.activeTopic$.subscribe((activeTopic) => {
|
||||
ngOnInit(): void {
|
||||
this.activeTopic$.pipe(untilDestroyed(this)).subscribe((activeTopic) => {
|
||||
if (activeTopic === 'WithdrawalsTopic') {
|
||||
this.form.addControl('walletID', this.fb.control(''));
|
||||
} else {
|
||||
@ -54,11 +48,11 @@ export class CreateWebhookFormComponent implements OnInit {
|
||||
});
|
||||
}
|
||||
|
||||
changeActiveTopic(topic: TopicEnum) {
|
||||
changeActiveTopic(topic: TopicEnum): void {
|
||||
this.activeTopic$.next(topic);
|
||||
}
|
||||
|
||||
get eventTypes() {
|
||||
get eventTypes(): FormArray {
|
||||
return this.form.get('eventTypes') as FormArray;
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ import { CommonModule } from '@angular/common';
|
||||
import { NgModule } from '@angular/core';
|
||||
import { FlexModule } from '@angular/flex-layout';
|
||||
import { ReactiveFormsModule } from '@angular/forms';
|
||||
import { MatAutocompleteModule } from '@angular/material/autocomplete';
|
||||
import { MatCheckboxModule } from '@angular/material/checkbox';
|
||||
import { MatDialogModule } from '@angular/material/dialog';
|
||||
import { MatDividerModule } from '@angular/material/divider';
|
||||
@ -12,6 +13,7 @@ import { MatSelectModule } from '@angular/material/select';
|
||||
import { TranslocoModule } from '@ngneat/transloco';
|
||||
|
||||
import { BaseDialogModule } from '@dsh/app/shared/components/dialog/base-dialog';
|
||||
import { WalletAutocompleteFieldModule } from '@dsh/app/shared/components/inputs/wallet-autocomplete-field';
|
||||
import { ButtonModule } from '@dsh/components/buttons';
|
||||
|
||||
import { CreateWebhookDialogComponent } from './create-webhook-dialog.component';
|
||||
@ -33,6 +35,8 @@ import { CreateWebhookService } from './create-webhook.service';
|
||||
MatCheckboxModule,
|
||||
MatInputModule,
|
||||
BaseDialogModule,
|
||||
MatAutocompleteModule,
|
||||
WalletAutocompleteFieldModule,
|
||||
],
|
||||
declarations: [CreateWebhookDialogComponent, CreateWebhookFormComponent],
|
||||
providers: [CreateWebhookService],
|
||||
|
@ -31,10 +31,10 @@
|
||||
<mat-label>{{ t('withdrawalID') }}</mat-label>
|
||||
<input matInput type="text" formControlName="withdrawalID" />
|
||||
</mat-form-field>
|
||||
<mat-form-field fxFlex>
|
||||
<mat-label>{{ t('walletID') }}</mat-label>
|
||||
<input matInput type="text" formControlName="walletID" />
|
||||
</mat-form-field>
|
||||
<dsh-wallet-autocomplete-field
|
||||
fxFlex
|
||||
[control]="form?.controls?.walletID"
|
||||
></dsh-wallet-autocomplete-field>
|
||||
</div>
|
||||
<div fxLayout fxLayout.sm="column" fxLayoutGap="20px">
|
||||
<mat-form-field fxFlex>
|
||||
|
@ -11,11 +11,14 @@ import { SearchFormService } from './search-form.service';
|
||||
})
|
||||
export class SearchFormComponent {
|
||||
form = this.searchFormService.form;
|
||||
reset = this.searchFormService.reset;
|
||||
|
||||
withdrawalStatuses: WithdrawalStatus.StatusEnum[] = ['Pending', 'Succeeded', 'Failed'];
|
||||
|
||||
expanded = false;
|
||||
|
||||
constructor(private searchFormService: SearchFormService) {}
|
||||
|
||||
reset(): void {
|
||||
this.searchFormService.reset();
|
||||
}
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ import { ActivatedRoute, Router } from '@angular/router';
|
||||
import moment from 'moment';
|
||||
import { map, startWith } from 'rxjs/operators';
|
||||
|
||||
import { removeEmptyProperties } from '../../../payment-section/operations/operators';
|
||||
import { WithdrawalsService } from '../withdrawals.service';
|
||||
import { FormParams } from './form-params';
|
||||
import { toFormValue } from './to-form-value';
|
||||
@ -38,24 +39,26 @@ export class SearchFormService {
|
||||
this.init();
|
||||
}
|
||||
|
||||
search(value) {
|
||||
search(value): void {
|
||||
this.depositsService.search(toSearchParams(value));
|
||||
}
|
||||
|
||||
reset() {
|
||||
reset(): void {
|
||||
this.form.setValue(SearchFormService.defaultParams);
|
||||
}
|
||||
|
||||
private init() {
|
||||
private init(): void {
|
||||
this.syncQueryParams();
|
||||
this.form.valueChanges.pipe(startWith(this.form.value)).subscribe((v) => this.search(v));
|
||||
this.form.valueChanges.pipe(startWith(this.form.value), removeEmptyProperties).subscribe((v) => this.search(v));
|
||||
}
|
||||
|
||||
private syncQueryParams() {
|
||||
private syncQueryParams(): void {
|
||||
const formValue = toFormValue(this.route.snapshot.queryParams, SearchFormService.defaultParams);
|
||||
this.form.setValue(formValue);
|
||||
this.form.valueChanges.pipe(startWith(formValue), map(toQueryParams)).subscribe((queryParams) => {
|
||||
this.router.navigate([location.pathname], { queryParams });
|
||||
});
|
||||
this.form.valueChanges
|
||||
.pipe(startWith(formValue), removeEmptyProperties, map(toQueryParams))
|
||||
.subscribe((queryParams) => {
|
||||
this.router.navigate([location.pathname], { queryParams });
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -8,6 +8,7 @@ import { MatSelectModule } from '@angular/material/select';
|
||||
import { TranslocoModule } from '@ngneat/transloco';
|
||||
|
||||
import { WithdrawalsModule as WithdrawalsApiModule } from '@dsh/api/withdrawals';
|
||||
import { WalletAutocompleteFieldModule } from '@dsh/app/shared/components/inputs/wallet-autocomplete-field';
|
||||
import { ToMajorModule } from '@dsh/app/shared/pipes';
|
||||
import { ButtonModule } from '@dsh/components/buttons';
|
||||
import { RangeDatepickerModule } from '@dsh/components/form-controls';
|
||||
@ -50,6 +51,7 @@ import { WithdrawalsComponent } from './withdrawals.component';
|
||||
InvoiceDetailsModule,
|
||||
WalletSectionModule,
|
||||
WithdrawalInfoModule,
|
||||
WalletAutocompleteFieldModule,
|
||||
],
|
||||
declarations: [WithdrawalsComponent, SearchFormComponent, WithdrawalListComponent],
|
||||
})
|
||||
|
@ -0,0 +1,15 @@
|
||||
<mat-form-field fxFlex>
|
||||
<mat-label>{{ title }}</mat-label>
|
||||
<input *ngIf="!options; else autocomplete" type="text" matInput [formControl]="control" />
|
||||
<ng-template #autocomplete>
|
||||
<input [required]="required" type="text" matInput [formControl]="control" [matAutocomplete]="auto" />
|
||||
<mat-autocomplete #auto="matAutocomplete" [displayWith]="displayLabel">
|
||||
<mat-option *ngFor="let option of filteredOptions$ | async" [value]="option.value">
|
||||
{{ option.label }}
|
||||
</mat-option>
|
||||
</mat-autocomplete>
|
||||
</ng-template>
|
||||
<button *ngIf="control?.value" dsh-icon-button matSuffix (click)="clearValue()">
|
||||
<mat-icon svgIcon="cross"></mat-icon>
|
||||
</button>
|
||||
</mat-form-field>
|
@ -0,0 +1,50 @@
|
||||
import { Component, Input, OnInit } from '@angular/core';
|
||||
import { FormControl } from '@ngneat/reactive-forms';
|
||||
import { Observable } from 'rxjs';
|
||||
import { map, startWith } from 'rxjs/operators';
|
||||
|
||||
import { coerceBoolean } from '@dsh/utils';
|
||||
|
||||
import { Option } from './types';
|
||||
|
||||
@Component({
|
||||
selector: 'dsh-autocomplete-field',
|
||||
templateUrl: 'autocomplete-field.component.html',
|
||||
})
|
||||
export class AutocompleteFieldComponent implements OnInit {
|
||||
@Input() control: FormControl;
|
||||
|
||||
@Input() title: string;
|
||||
|
||||
@Input() options: Option[];
|
||||
|
||||
filteredOptions$: Observable<Option[]>;
|
||||
|
||||
@Input() @coerceBoolean required = false;
|
||||
|
||||
constructor() {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
||||
this.displayLabel = this.displayLabel.bind(this);
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.filteredOptions$ = this.control.valueChanges.pipe(
|
||||
startWith(this.control.value),
|
||||
map((searchValue) => (searchValue ? this.filterOptions(searchValue) : this.options))
|
||||
);
|
||||
}
|
||||
|
||||
displayLabel(selectedValue: unknown): string {
|
||||
const label = this.options?.find((option) => option.value === selectedValue)?.label;
|
||||
return label ? label : '';
|
||||
}
|
||||
|
||||
clearValue(): void {
|
||||
this.control.reset();
|
||||
}
|
||||
|
||||
private filterOptions(searchValue: string): Option[] {
|
||||
const filterValue = searchValue.toLowerCase();
|
||||
return this.options?.filter((option) => option.label.toLowerCase().includes(filterValue));
|
||||
}
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { NgModule } from '@angular/core';
|
||||
import { FlexLayoutModule } from '@angular/flex-layout';
|
||||
import { ReactiveFormsModule } from '@angular/forms';
|
||||
import { MatAutocompleteModule } from '@angular/material/autocomplete';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
import { MatFormFieldModule } from '@angular/material/form-field';
|
||||
import { MatIconModule } from '@angular/material/icon';
|
||||
import { MatInputModule } from '@angular/material/input';
|
||||
|
||||
import { ButtonModule } from '@dsh/components/buttons';
|
||||
|
||||
import { AutocompleteFieldComponent } from './autocomplete-field.component';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
CommonModule,
|
||||
MatFormFieldModule,
|
||||
MatInputModule,
|
||||
ReactiveFormsModule,
|
||||
FlexLayoutModule,
|
||||
MatAutocompleteModule,
|
||||
MatButtonModule,
|
||||
MatIconModule,
|
||||
ButtonModule,
|
||||
],
|
||||
declarations: [AutocompleteFieldComponent],
|
||||
exports: [AutocompleteFieldComponent],
|
||||
})
|
||||
export class AutocompleteFieldModule {}
|
@ -0,0 +1,3 @@
|
||||
export * from './autocomplete-field.module';
|
||||
export * from './autocomplete-field.component';
|
||||
export * from './types';
|
@ -0,0 +1 @@
|
||||
export * from './option';
|
@ -0,0 +1,4 @@
|
||||
export interface Option<T = any> {
|
||||
value: T;
|
||||
label: string;
|
||||
}
|
@ -0,0 +1,2 @@
|
||||
export * from './wallet-autocomplete-field.module';
|
||||
export * from './wallet-autocomplete-field.component';
|
@ -0,0 +1,6 @@
|
||||
import { Wallet } from '@dsh/api-codegen/wallet-api';
|
||||
import { Option } from '@dsh/app/shared/components/inputs/autocomplete-field';
|
||||
|
||||
export function walletsToOptions(wallets: Wallet[]): Option[] {
|
||||
return wallets.map((wallet) => ({ label: wallet.name, value: wallet.id }));
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
<dsh-autocomplete-field
|
||||
*transloco="let t; scope: 'wallet-autocomplete-field'; read: 'walletAutocompleteField'"
|
||||
[title]="t('title')"
|
||||
[control]="control"
|
||||
[options]="options$ | async"
|
||||
></dsh-autocomplete-field>
|
@ -0,0 +1,23 @@
|
||||
import { Component, Input } from '@angular/core';
|
||||
import { FormControl } from '@ngneat/reactive-forms';
|
||||
import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy';
|
||||
import { map, shareReplay } from 'rxjs/operators';
|
||||
|
||||
import { WalletService } from '@dsh/api';
|
||||
import { walletsToOptions } from '@dsh/app/shared/components/inputs/wallet-autocomplete-field/utils/wallets-to-options';
|
||||
import { coerceBoolean } from '@dsh/utils';
|
||||
|
||||
@UntilDestroy()
|
||||
@Component({
|
||||
selector: 'dsh-wallet-autocomplete-field',
|
||||
templateUrl: 'wallet-autocomplete-field.component.html',
|
||||
})
|
||||
export class WalletAutocompleteFieldComponent {
|
||||
@Input() control: FormControl;
|
||||
|
||||
options$ = this.walletService.wallets$.pipe(map(walletsToOptions), untilDestroyed(this), shareReplay(1));
|
||||
|
||||
@Input() @coerceBoolean required = false;
|
||||
|
||||
constructor(private walletService: WalletService) {}
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { NgModule } from '@angular/core';
|
||||
import { TranslocoModule } from '@ngneat/transloco';
|
||||
|
||||
import { AutocompleteFieldModule } from '@dsh/app/shared/components/inputs/autocomplete-field';
|
||||
|
||||
import { WalletAutocompleteFieldComponent } from './wallet-autocomplete-field.component';
|
||||
|
||||
@NgModule({
|
||||
imports: [CommonModule, TranslocoModule, AutocompleteFieldModule],
|
||||
declarations: [WalletAutocompleteFieldComponent],
|
||||
exports: [WalletAutocompleteFieldComponent],
|
||||
})
|
||||
export class WalletAutocompleteFieldModule {}
|
3
src/assets/i18n/wallet-autocomplete-field/ru.json
Normal file
3
src/assets/i18n/wallet-autocomplete-field/ru.json
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"title": "Кошелек"
|
||||
}
|
Loading…
Reference in New Issue
Block a user