mirror of
https://github.com/valitydev/control-center.git
synced 2024-11-06 02:25:17 +00:00
IMP-301: New shop selector (#381)
This commit is contained in:
parent
6a990a79ea
commit
55d2817cd8
@ -18,8 +18,8 @@ import { ROUTING_CONFIG as REPAIRING_ROUTING_CONFIG } from './sections/repairing
|
||||
import { ROUTING_CONFIG as PARTIES_ROUTING_CONFIG } from './sections/search-parties/routing-config';
|
||||
import { SHOPS_ROUTING_CONFIG } from './sections/shops';
|
||||
import { ROUTING_CONFIG as SOURCES_ROUTING_CONFIG } from './sections/sources/routing-config';
|
||||
import { ROUTING_CONFIG as TARIFFS_ROUTING_CONFIG } from './sections/tariffs/routing-config';
|
||||
import { ROUTING_CONFIG as TERMINALS_ROUTING_CONFIG } from './sections/terminals';
|
||||
import { ROUTING_CONFIG as TERMS_ROUTING_CONFIG } from './sections/terms/routing-config';
|
||||
import { ROUTING_CONFIG as WALLETS_ROUTING_CONFIG } from './sections/wallets/routing-config';
|
||||
import { ROUTING_CONFIG as WITHDRAWALS_ROUTING_CONFIG } from './sections/withdrawals/routing-config';
|
||||
import { SidenavInfoService } from './shared/components/sidenav-info';
|
||||
@ -84,7 +84,7 @@ export class AppComponent {
|
||||
{
|
||||
label: 'Terms',
|
||||
url: '/terms',
|
||||
services: TARIFFS_ROUTING_CONFIG.services,
|
||||
services: TERMS_ROUTING_CONFIG.services,
|
||||
},
|
||||
],
|
||||
[
|
||||
|
@ -70,7 +70,7 @@ const ROUTES: Routes = [
|
||||
},
|
||||
{
|
||||
path: 'terms',
|
||||
loadChildren: () => import('./tariffs').then((m) => m.TariffsModule),
|
||||
loadChildren: () => import('./terms').then((m) => m.Terms),
|
||||
},
|
||||
{
|
||||
path: '404',
|
||||
|
@ -1 +0,0 @@
|
||||
export * from './tariffs.module';
|
@ -1,10 +0,0 @@
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { NgModule } from '@angular/core';
|
||||
|
||||
import { ShopsTariffsComponent } from './components/shops-tariffs/shops-tariffs.component';
|
||||
import { TariffsRoutingModule } from './tariffs-routing.module';
|
||||
|
||||
@NgModule({
|
||||
imports: [CommonModule, TariffsRoutingModule, ShopsTariffsComponent],
|
||||
})
|
||||
export class TariffsModule {}
|
@ -12,7 +12,7 @@ import {
|
||||
getShopCashFlowSelectors,
|
||||
isShopTermSetDecision,
|
||||
SHOP_FEES_COLUMNS,
|
||||
} from '../shops-tariffs/utils/shop-fees-columns';
|
||||
} from '../shops-terms/utils/shop-fees-columns';
|
||||
|
||||
@Component({
|
||||
selector: 'cc-shops-term-set-history-card',
|
@ -21,7 +21,7 @@
|
||||
[hasMore]="hasMore$ | async"
|
||||
[maxSize]="250"
|
||||
[progress]="isLoading$ | async"
|
||||
[treeData]="tariffs$ | async"
|
||||
[treeData]="terms$ | async"
|
||||
(more)="more()"
|
||||
(update)="update($event)"
|
||||
></v-table2>
|
@ -43,7 +43,7 @@ import {
|
||||
import { getInlineDecisions2, InlineDecision2 } from '../../utils/get-inline-decisions';
|
||||
import { ShopsTermSetHistoryCardComponent } from '../shops-term-set-history-card';
|
||||
|
||||
import { ShopsTariffsService } from './shops-tariffs.service';
|
||||
import { ShopsTermsService } from './shops-terms.service';
|
||||
import {
|
||||
isShopTermSetDecision,
|
||||
SHOP_FEES_COLUMNS,
|
||||
@ -57,7 +57,7 @@ type Params = Pick<CommonSearchQueryParams, 'currencies'> &
|
||||
>;
|
||||
|
||||
@Component({
|
||||
selector: 'cc-shops-tariffs',
|
||||
selector: 'cc-shops-terms',
|
||||
standalone: true,
|
||||
imports: [
|
||||
CommonModule,
|
||||
@ -73,9 +73,9 @@ type Params = Pick<CommonSearchQueryParams, 'currencies'> &
|
||||
VSelectPipe,
|
||||
MatTooltip,
|
||||
],
|
||||
templateUrl: './shops-tariffs.component.html',
|
||||
templateUrl: './shops-terms.component.html',
|
||||
})
|
||||
export class ShopsTariffsComponent implements OnInit {
|
||||
export class ShopsTermsComponent implements OnInit {
|
||||
filtersForm = this.fb.group(
|
||||
createControls<Params>({
|
||||
currencies: null,
|
||||
@ -85,7 +85,7 @@ export class ShopsTariffsComponent implements OnInit {
|
||||
term_sets_ids: null,
|
||||
}),
|
||||
);
|
||||
tariffs$ = this.shopsTariffsService.result$.pipe(
|
||||
terms$ = this.shopsTermsService.result$.pipe(
|
||||
map((terms) =>
|
||||
terms.map((t) => ({
|
||||
value: t,
|
||||
@ -100,8 +100,8 @@ export class ShopsTariffsComponent implements OnInit {
|
||||
})),
|
||||
),
|
||||
);
|
||||
hasMore$ = this.shopsTariffsService.hasMore$;
|
||||
isLoading$ = this.shopsTariffsService.isLoading$;
|
||||
hasMore$ = this.shopsTermsService.hasMore$;
|
||||
isLoading$ = this.shopsTermsService.isLoading$;
|
||||
columns: Column2<ShopTermSet, InlineDecision2>[] = [
|
||||
createShopColumn(
|
||||
(d) => ({
|
||||
@ -138,7 +138,7 @@ export class ShopsTariffsComponent implements OnInit {
|
||||
private initFiltersValue = this.filtersForm.value;
|
||||
|
||||
constructor(
|
||||
private shopsTariffsService: ShopsTariffsService,
|
||||
private shopsTermsService: ShopsTermsService,
|
||||
private fb: NonNullableFormBuilder,
|
||||
private qp: QueryParamsService<Params>,
|
||||
@Inject(DEBOUNCE_TIME_MS) private debounceTimeMs: number,
|
||||
@ -158,7 +158,7 @@ export class ShopsTariffsComponent implements OnInit {
|
||||
|
||||
load(params: Params, options?: LoadOptions) {
|
||||
const { currencies, term_sets_ids, ...otherParams } = params;
|
||||
this.shopsTariffsService.load(
|
||||
this.shopsTermsService.load(
|
||||
clean({
|
||||
common_search_query_params: { currencies },
|
||||
term_sets_ids: term_sets_ids?.map?.((id) => ({ id })),
|
||||
@ -169,10 +169,10 @@ export class ShopsTariffsComponent implements OnInit {
|
||||
}
|
||||
|
||||
update(options?: UpdateOptions) {
|
||||
this.shopsTariffsService.reload(options);
|
||||
this.shopsTermsService.reload(options);
|
||||
}
|
||||
|
||||
more() {
|
||||
this.shopsTariffsService.more();
|
||||
this.shopsTermsService.more();
|
||||
}
|
||||
}
|
@ -14,7 +14,7 @@ import { DominatorService } from '@cc/app/api/dominator';
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class ShopsTariffsService extends FetchSuperclass<ShopTermSet, ShopSearchQuery> {
|
||||
export class ShopsTermsService extends FetchSuperclass<ShopTermSet, ShopSearchQuery> {
|
||||
constructor(
|
||||
private dominatorService: DominatorService,
|
||||
private log: NotifyLogService,
|
@ -18,7 +18,7 @@
|
||||
wallets: arrayColumnTemplate
|
||||
}"
|
||||
[columns]="columns"
|
||||
[data]="tariffs$ | async"
|
||||
[data]="terms$ | async"
|
||||
[hasMore]="hasMore$ | async"
|
||||
[progress]="isLoading$ | async"
|
||||
(more)="more()"
|
@ -48,7 +48,7 @@ type Params = Pick<CommonSearchQueryParams, 'currencies'> &
|
||||
>;
|
||||
|
||||
@Component({
|
||||
selector: 'cc-terminals-tariffs',
|
||||
selector: 'cc-terminals-terms',
|
||||
standalone: true,
|
||||
imports: [
|
||||
CommonModule,
|
||||
@ -73,7 +73,7 @@ export class TerminalsTermsComponent implements OnInit {
|
||||
terminal_ids: null,
|
||||
}),
|
||||
);
|
||||
tariffs$ = this.terminalsTermsService.result$;
|
||||
terms$ = this.terminalsTermsService.result$;
|
||||
hasMore$ = this.terminalsTermsService.hasMore$;
|
||||
isLoading$ = this.terminalsTermsService.isLoading$;
|
||||
columns: Column<TerminalTermSet>[] = [
|
@ -12,7 +12,7 @@ import {
|
||||
WALLET_FEES_COLUMNS,
|
||||
isWalletTermSetDecision,
|
||||
getWalletCashFlowSelectors,
|
||||
} from '../wallets-tariffs/utils/wallet-fees-columns';
|
||||
} from '../wallets-terms/utils/wallet-fees-columns';
|
||||
|
||||
@Component({
|
||||
selector: 'cc-wallets-term-set-history-card',
|
@ -18,7 +18,7 @@
|
||||
[hasMore]="hasMore$ | async"
|
||||
[maxSize]="250"
|
||||
[progress]="isLoading$ | async"
|
||||
[treeData]="tariffs$ | async"
|
||||
[treeData]="terms$ | async"
|
||||
(more)="more()"
|
||||
(update)="update($event)"
|
||||
></v-table2>
|
@ -50,7 +50,7 @@ import {
|
||||
getWalletCashFlowSelectors,
|
||||
isWalletTermSetDecision,
|
||||
} from './utils/wallet-fees-columns';
|
||||
import { WalletsTariffsService } from './wallets-tariffs.service';
|
||||
import { WalletsTermsService } from './wallets-terms.service';
|
||||
|
||||
type Params = Pick<CommonSearchQueryParams, 'currencies'> &
|
||||
Overwrite<
|
||||
@ -59,7 +59,7 @@ type Params = Pick<CommonSearchQueryParams, 'currencies'> &
|
||||
>;
|
||||
|
||||
@Component({
|
||||
selector: 'cc-wallets-tariffs',
|
||||
selector: 'cc-wallets-terms',
|
||||
standalone: true,
|
||||
imports: [
|
||||
CommonModule,
|
||||
@ -75,9 +75,9 @@ type Params = Pick<CommonSearchQueryParams, 'currencies'> &
|
||||
MatTooltip,
|
||||
VSelectPipe,
|
||||
],
|
||||
templateUrl: './wallets-tariffs.component.html',
|
||||
templateUrl: './wallets-terms.component.html',
|
||||
})
|
||||
export class WalletsTariffsComponent implements OnInit {
|
||||
export class WalletsTermsComponent implements OnInit {
|
||||
filtersForm = this.fb.group(
|
||||
createControls<Params>({
|
||||
currencies: null,
|
||||
@ -88,7 +88,7 @@ export class WalletsTariffsComponent implements OnInit {
|
||||
identity_ids: null,
|
||||
}),
|
||||
);
|
||||
tariffs$ = this.walletsTariffsService.result$.pipe(
|
||||
terms$ = this.walletsTermsService.result$.pipe(
|
||||
map((terms) =>
|
||||
terms.map((t) => ({
|
||||
value: t,
|
||||
@ -104,8 +104,8 @@ export class WalletsTariffsComponent implements OnInit {
|
||||
})),
|
||||
),
|
||||
);
|
||||
hasMore$ = this.walletsTariffsService.hasMore$;
|
||||
isLoading$ = this.walletsTariffsService.isLoading$;
|
||||
hasMore$ = this.walletsTermsService.hasMore$;
|
||||
isLoading$ = this.walletsTermsService.isLoading$;
|
||||
columns: Column2<WalletTermSet, InlineDecision2>[] = [
|
||||
createWalletColumn((d) => ({ id: d.wallet_id, name: d.wallet_name, partyId: d.owner_id }), {
|
||||
sticky: 'start',
|
||||
@ -135,7 +135,7 @@ export class WalletsTariffsComponent implements OnInit {
|
||||
private initFiltersValue = this.filtersForm.value;
|
||||
|
||||
constructor(
|
||||
private walletsTariffsService: WalletsTariffsService,
|
||||
private walletsTermsService: WalletsTermsService,
|
||||
private fb: NonNullableFormBuilder,
|
||||
private qp: QueryParamsService<Params>,
|
||||
@Inject(DEBOUNCE_TIME_MS) private debounceTimeMs: number,
|
||||
@ -155,7 +155,7 @@ export class WalletsTariffsComponent implements OnInit {
|
||||
|
||||
load(params: Params, options?: LoadOptions) {
|
||||
const { currencies, term_sets_ids, identity_ids, ...otherParams } = params;
|
||||
this.walletsTariffsService.load(
|
||||
this.walletsTermsService.load(
|
||||
clean({
|
||||
common_search_query_params: { currencies },
|
||||
term_sets_ids: term_sets_ids?.map?.((id) => ({ id })),
|
||||
@ -167,10 +167,10 @@ export class WalletsTariffsComponent implements OnInit {
|
||||
}
|
||||
|
||||
update(options?: UpdateOptions) {
|
||||
this.walletsTariffsService.reload(options);
|
||||
this.walletsTermsService.reload(options);
|
||||
}
|
||||
|
||||
more() {
|
||||
this.walletsTariffsService.more();
|
||||
this.walletsTermsService.more();
|
||||
}
|
||||
}
|
@ -17,7 +17,7 @@ import { DominatorService } from '@cc/app/api/dominator';
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class WalletsTariffsService extends FetchSuperclass<WalletTermSet, WalletSearchQuery> {
|
||||
export class WalletsTermsService extends FetchSuperclass<WalletTermSet, WalletSearchQuery> {
|
||||
constructor(
|
||||
private dominatorService: DominatorService,
|
||||
private log: NotifyLogService,
|
1
src/app/sections/terms/index.ts
Normal file
1
src/app/sections/terms/index.ts
Normal file
@ -0,0 +1 @@
|
||||
export * from './terms';
|
@ -3,28 +3,28 @@ import { RouterModule } from '@angular/router';
|
||||
|
||||
import { AppAuthGuardService } from '../../shared/services';
|
||||
|
||||
import { ShopsTariffsComponent } from './components/shops-tariffs/shops-tariffs.component';
|
||||
import { ShopsTermsComponent } from './components/shops-terms/shops-terms.component';
|
||||
import { TerminalsTermsComponent } from './components/terminals-terms/terminals-terms.component';
|
||||
import { WalletsTariffsComponent } from './components/wallets-tariffs/wallets-tariffs.component';
|
||||
import { WalletsTermsComponent } from './components/wallets-terms/wallets-terms.component';
|
||||
import { ROUTING_CONFIG } from './routing-config';
|
||||
import { TariffsComponent } from './tariffs.component';
|
||||
import { TermsComponent } from './terms.component';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
RouterModule.forChild([
|
||||
{
|
||||
path: '',
|
||||
component: TariffsComponent,
|
||||
component: TermsComponent,
|
||||
canActivate: [AppAuthGuardService],
|
||||
data: ROUTING_CONFIG,
|
||||
children: [
|
||||
{
|
||||
path: 'shops',
|
||||
component: ShopsTariffsComponent,
|
||||
component: ShopsTermsComponent,
|
||||
},
|
||||
{
|
||||
path: 'wallets',
|
||||
component: WalletsTariffsComponent,
|
||||
component: WalletsTermsComponent,
|
||||
},
|
||||
{
|
||||
path: 'terminals',
|
||||
@ -41,4 +41,4 @@ import { TariffsComponent } from './tariffs.component';
|
||||
],
|
||||
exports: [RouterModule],
|
||||
})
|
||||
export class TariffsRoutingModule {}
|
||||
export class TermsRoutingModule {}
|
@ -7,12 +7,12 @@ import { Link, NavComponent } from '@vality/ng-core';
|
||||
import { SidenavInfoService } from '@cc/app/shared/components/sidenav-info';
|
||||
|
||||
@Component({
|
||||
selector: 'cc-tariffs',
|
||||
selector: 'cc-terms',
|
||||
standalone: true,
|
||||
imports: [CommonModule, RouterOutlet, MatSidenavModule, NavComponent],
|
||||
templateUrl: './tariffs.component.html',
|
||||
templateUrl: './terms.component.html',
|
||||
})
|
||||
export class TariffsComponent {
|
||||
export class TermsComponent {
|
||||
links: Link[] = [
|
||||
{
|
||||
label: 'Shops',
|
10
src/app/sections/terms/terms.ts
Normal file
10
src/app/sections/terms/terms.ts
Normal file
@ -0,0 +1,10 @@
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { NgModule } from '@angular/core';
|
||||
|
||||
import { ShopsTermsComponent } from './components/shops-terms/shops-terms.component';
|
||||
import { TermsRoutingModule } from './terms-routing.module';
|
||||
|
||||
@NgModule({
|
||||
imports: [CommonModule, TermsRoutingModule, ShopsTermsComponent],
|
||||
})
|
||||
export class Terms {}
|
@ -1,8 +1,13 @@
|
||||
<mat-form-field>
|
||||
<mat-label>{{ multiple ? 'Shops' : 'Shop' }}</mat-label>
|
||||
<mat-select [formControl]="control" [multiple]="multiple" [required]="required">
|
||||
<mat-option *ngFor="let shop of shops$ | async" [value]="shop.id">
|
||||
{{ shop.details.name }}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
<v-select-field
|
||||
[appearance]="appearance"
|
||||
[formControl]="control"
|
||||
[hint]="hint"
|
||||
[label]="label || (multiple ? 'Shops' : 'Shop')"
|
||||
[multiple]="multiple"
|
||||
[options]="options$ | async"
|
||||
[progress]="!!(progress$ | async)"
|
||||
[required]="required"
|
||||
[size]="size"
|
||||
externalSearch
|
||||
(searchChange)="this.searchChange$.next($event)"
|
||||
></v-select-field>
|
||||
|
@ -1,8 +0,0 @@
|
||||
:host {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
mat-form-field {
|
||||
width: 100%;
|
||||
}
|
@ -1,92 +1,160 @@
|
||||
import {
|
||||
ChangeDetectionStrategy,
|
||||
Component,
|
||||
Input,
|
||||
OnChanges,
|
||||
OnInit,
|
||||
booleanAttribute,
|
||||
DestroyRef,
|
||||
inject,
|
||||
AfterViewInit,
|
||||
input,
|
||||
Injector,
|
||||
} from '@angular/core';
|
||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
||||
import { Shop } from '@vality/domain-proto/domain';
|
||||
import { PartyID, ShopID } from '@vality/domain-proto/payment_processing';
|
||||
import { takeUntilDestroyed, toObservable } from '@angular/core/rxjs-interop';
|
||||
import { PartyID, Shop, Party } from '@vality/domain-proto/internal/domain';
|
||||
import { ShopID } from '@vality/domain-proto/payment_processing';
|
||||
import {
|
||||
createControlProviders,
|
||||
FormControlSuperclass,
|
||||
setDisabled,
|
||||
isEmpty,
|
||||
ComponentChanges,
|
||||
debounceTimeWithFirst,
|
||||
Option,
|
||||
NotifyLogService,
|
||||
progressTo,
|
||||
} from '@vality/ng-core';
|
||||
import { BehaviorSubject, defer, of } from 'rxjs';
|
||||
import { filter, map, share, switchMap } from 'rxjs/operators';
|
||||
import {
|
||||
BehaviorSubject,
|
||||
of,
|
||||
Subject,
|
||||
combineLatest,
|
||||
Observable,
|
||||
concat,
|
||||
scheduled,
|
||||
asyncScheduler,
|
||||
concatMap,
|
||||
} from 'rxjs';
|
||||
import { map, switchMap, distinctUntilChanged, catchError } from 'rxjs/operators';
|
||||
|
||||
import { PartyManagementService } from '@cc/app/api/payment-processing';
|
||||
import { DeanonimusService } from '../../../api/deanonimus';
|
||||
import { PartyManagementService } from '../../../api/payment-processing';
|
||||
import { DEBOUNCE_TIME_MS } from '../../../tokens';
|
||||
|
||||
@Component({
|
||||
selector: 'cc-shop-field',
|
||||
templateUrl: './shop-field.component.html',
|
||||
styleUrls: ['./shop-field.component.scss'],
|
||||
providers: createControlProviders(() => ShopFieldComponent),
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class ShopFieldComponent<M extends boolean = boolean>
|
||||
extends FormControlSuperclass<
|
||||
M extends true ? Shop[] : Shop,
|
||||
M extends true ? ShopID[] : ShopID
|
||||
>
|
||||
implements OnChanges, OnInit
|
||||
export class ShopFieldComponent
|
||||
extends FormControlSuperclass<ShopID | ShopID[]>
|
||||
implements AfterViewInit
|
||||
{
|
||||
@Input() partyId: PartyID;
|
||||
@Input({ transform: booleanAttribute }) multiple: M;
|
||||
@Input() label: string;
|
||||
@Input({ transform: booleanAttribute }) required: boolean;
|
||||
@Input() size?: string;
|
||||
@Input() appearance?: string;
|
||||
@Input() hint?: string;
|
||||
@Input({ transform: booleanAttribute }) multiple = false;
|
||||
partyId = input<PartyID>();
|
||||
|
||||
shops$ = defer(() => this.partyId$).pipe(
|
||||
switchMap((partyId) =>
|
||||
partyId
|
||||
? this.partyManagementService
|
||||
.Get(partyId)
|
||||
.pipe(map(({ shops }) => Array.from(shops.values())))
|
||||
: of<Shop[]>([]),
|
||||
),
|
||||
share(),
|
||||
);
|
||||
options$ = new BehaviorSubject<Option<ShopID>[]>([]);
|
||||
searchChange$ = new Subject<string>();
|
||||
progress$ = new BehaviorSubject(0);
|
||||
|
||||
private partyId$ = new BehaviorSubject<PartyID>(null);
|
||||
private debounceTimeMs = inject(DEBOUNCE_TIME_MS);
|
||||
|
||||
constructor(
|
||||
private partyManagementService: PartyManagementService,
|
||||
private destroyRef: DestroyRef,
|
||||
private deanonimusService: DeanonimusService,
|
||||
private log: NotifyLogService,
|
||||
private dr: DestroyRef,
|
||||
private injector: Injector,
|
||||
) {
|
||||
super();
|
||||
}
|
||||
|
||||
setDisabledState(isDisabled: boolean) {
|
||||
super.setDisabledState(!this.partyId || isDisabled);
|
||||
}
|
||||
|
||||
ngOnChanges(changes: ComponentChanges<ShopFieldComponent>): void {
|
||||
super.ngOnChanges(changes);
|
||||
if (changes.partyId && this.partyId !== this.partyId$.value) {
|
||||
this.partyId$.next(changes.partyId.currentValue);
|
||||
setDisabled(this.control, !this.partyId);
|
||||
}
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.shops$
|
||||
.pipe(
|
||||
filter(
|
||||
(shops) =>
|
||||
!isEmpty(this.control.value) &&
|
||||
(Array.isArray(this.control.value)
|
||||
? !this.control.value.every((v) => shops.some((s) => s.id === v))
|
||||
: !shops.some((s) => s.id === this.control.value)),
|
||||
ngAfterViewInit() {
|
||||
const initValues = this.getCurrentValues();
|
||||
combineLatest([
|
||||
concat(
|
||||
scheduled(initValues.length ? initValues : [''], asyncScheduler),
|
||||
this.searchChange$.pipe(
|
||||
distinctUntilChanged(),
|
||||
debounceTimeWithFirst(this.debounceTimeMs),
|
||||
),
|
||||
takeUntilDestroyed(this.destroyRef),
|
||||
),
|
||||
toObservable(this.partyId, { injector: this.injector }).pipe(
|
||||
switchMap((partyId) =>
|
||||
partyId
|
||||
? this.partyManagementService.Get(partyId).pipe(progressTo(this.progress$))
|
||||
: of(null),
|
||||
),
|
||||
),
|
||||
])
|
||||
.pipe(
|
||||
concatMap(([term, party]) =>
|
||||
party
|
||||
? of(this.searchShopsByParty(party, term))
|
||||
: this.searchShops(term).pipe(progressTo(this.progress$)),
|
||||
),
|
||||
takeUntilDestroyed(this.dr),
|
||||
)
|
||||
.subscribe(() => {
|
||||
this.control.setValue(null);
|
||||
.subscribe((options) => {
|
||||
const oldOptions = this.options$.value;
|
||||
this.options$.next(
|
||||
this.getCurrentValues().reduce((acc, v) => {
|
||||
if (acc.every((o) => o.value !== v)) {
|
||||
acc.push(
|
||||
oldOptions.find((f) => f.value === v) ?? {
|
||||
label: `#${v}`,
|
||||
value: v,
|
||||
description: v,
|
||||
},
|
||||
);
|
||||
}
|
||||
return acc;
|
||||
}, options),
|
||||
);
|
||||
});
|
||||
super.ngOnInit();
|
||||
}
|
||||
|
||||
private searchShops(search: string): Observable<Option<ShopID>[]> {
|
||||
return this.deanonimusService.searchShopText(search).pipe(
|
||||
map((partyShops) =>
|
||||
partyShops.map((p) => ({
|
||||
label: p.shop.details.name,
|
||||
value: p.shop.id,
|
||||
description: p.shop.id,
|
||||
})),
|
||||
),
|
||||
catchError((err) => {
|
||||
this.log.error(err, 'Search error');
|
||||
return of([]);
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
private searchShopsByParty(party: Party, search: string): Option<ShopID>[] {
|
||||
const searchStr = search.trim().toLowerCase();
|
||||
return Array.from(party.shops.values())
|
||||
.map((shop) => ({ party, shop }))
|
||||
.sort(
|
||||
(a, b) =>
|
||||
+this.includeSearchStr(a, searchStr) - +this.includeSearchStr(b, searchStr),
|
||||
)
|
||||
.map((p) => ({
|
||||
label: p.shop.details.name,
|
||||
value: p.shop.id,
|
||||
description: p.shop.id,
|
||||
}));
|
||||
}
|
||||
|
||||
private includeSearchStr({ shop, party }: { party: Party; shop: Shop }, searchStr: string) {
|
||||
return [shop.id, shop.details.name, party.id, party.party_name].some((v) =>
|
||||
String(v ?? '')
|
||||
.toLowerCase()
|
||||
.includes(searchStr),
|
||||
);
|
||||
}
|
||||
|
||||
private getCurrentValues() {
|
||||
const v = this.control.value;
|
||||
return v ? (Array.isArray(v) ? v : [v]) : [];
|
||||
}
|
||||
}
|
||||
|
@ -3,12 +3,20 @@ import { NgModule } from '@angular/core';
|
||||
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||
import { MatFormFieldModule } from '@angular/material/form-field';
|
||||
import { MatSelectModule } from '@angular/material/select';
|
||||
import { SelectFieldModule } from '@vality/ng-core';
|
||||
|
||||
import { ShopFieldComponent } from './shop-field.component';
|
||||
|
||||
@NgModule({
|
||||
declarations: [ShopFieldComponent],
|
||||
imports: [CommonModule, MatFormFieldModule, MatSelectModule, FormsModule, ReactiveFormsModule],
|
||||
imports: [
|
||||
CommonModule,
|
||||
MatFormFieldModule,
|
||||
MatSelectModule,
|
||||
FormsModule,
|
||||
ReactiveFormsModule,
|
||||
SelectFieldModule,
|
||||
],
|
||||
exports: [ShopFieldComponent],
|
||||
})
|
||||
export class ShopFieldModule {}
|
||||
|
Loading…
Reference in New Issue
Block a user