From bf8c021c9d37d8b7e2918c7056c8b5f02ac67e6f Mon Sep 17 00:00:00 2001 From: Rinat Arsaev <11846445+A77AY@users.noreply.github.com> Date: Fri, 13 Oct 2023 22:56:59 +0700 Subject: [PATCH] IMP-84: Add duplicate shop delegates, new parties, shops table (#273) --- package-lock.json | 8 +- package.json | 2 +- .../party-shops/party-shops.component.html | 24 ++- .../party-shops/party-shops.component.ts | 183 +++++++++++++++++- .../party-shops/party-shops.module.ts | 25 +-- .../party-shops/party-shops.service.ts | 19 +- .../shops-table/shops-table.component.html | 51 ----- .../shops-table/shops-table.component.scss | 11 -- .../shops-table/shops-table.component.ts | 43 ---- .../sections/party/party-routing.module.ts | 5 - .../party-delegate-rulesets.component.html | 30 ++- .../party-delegate-rulesets.component.ts | 2 +- .../party-routing-ruleset.component.html | 6 +- .../party-routing-ruleset.component.ts | 11 +- .../routing-rules-list.component.html | 71 +------ .../routing-rules-list.component.spec.ts | 34 ---- .../routing-rules-list.component.ts | 114 +++++++---- .../routing-rules-list.module.ts | 5 +- .../routing-ruleset.component.ts | 46 ++++- .../search-parties/parties-table/index.ts | 1 - .../parties-table.component.html | 36 ---- .../parties-table.component.scss | 7 - .../parties-table/parties-table.component.ts | 32 --- .../parties-table/parties-table.module.ts | 16 -- .../parties-table/party-actions.pipe.ts | 16 -- .../parties-table/party-actions.ts | 3 - .../parties-table/party-menu-item-event.ts | 8 - .../search-parties.component.html | 18 +- .../search-parties.component.ts | 58 +++++- .../search-parties/search-parties.module.ts | 4 +- src/app/sections/shop-details/index.ts | 1 - .../sections/shop-details/routing-config.ts | 5 - .../services/fetch-shop.service.ts | 61 ------ .../shop-details-routing.module.ts | 21 -- .../shop-details/shop-details.component.html | 42 ---- .../shop-details/shop-details.component.ts | 112 ----------- .../shop-details/shop-details.module.ts | 32 --- .../domain-thrift-form-dialog.component.html | 4 +- .../domain-thrift-form-dialog.component.ts | 12 +- .../domain-thrift-form.component.html | 4 +- .../domain-thrift-form.component.ts | 3 +- .../domain-thrift-viewer.component.html | 1 + .../domain-thrift-viewer.component.ts | 2 + .../thrift-editor/thrift-editor.component.ts | 2 +- .../thrift-viewer.component.html | 65 ++++--- .../thrift-viewer/thrift-viewer.component.ts | 2 + .../thrift-viewer/thrift-viewer.module.ts | 2 + 47 files changed, 486 insertions(+), 774 deletions(-) delete mode 100644 src/app/sections/party-shops/shops-table/shops-table.component.html delete mode 100644 src/app/sections/party-shops/shops-table/shops-table.component.scss delete mode 100644 src/app/sections/party-shops/shops-table/shops-table.component.ts delete mode 100644 src/app/sections/routing-rules/routing-rules-list/routing-rules-list.component.spec.ts delete mode 100644 src/app/sections/search-parties/parties-table/index.ts delete mode 100644 src/app/sections/search-parties/parties-table/parties-table.component.html delete mode 100644 src/app/sections/search-parties/parties-table/parties-table.component.scss delete mode 100644 src/app/sections/search-parties/parties-table/parties-table.component.ts delete mode 100644 src/app/sections/search-parties/parties-table/parties-table.module.ts delete mode 100644 src/app/sections/search-parties/parties-table/party-actions.pipe.ts delete mode 100644 src/app/sections/search-parties/parties-table/party-actions.ts delete mode 100644 src/app/sections/search-parties/parties-table/party-menu-item-event.ts delete mode 100644 src/app/sections/shop-details/index.ts delete mode 100644 src/app/sections/shop-details/routing-config.ts delete mode 100644 src/app/sections/shop-details/services/fetch-shop.service.ts delete mode 100644 src/app/sections/shop-details/shop-details-routing.module.ts delete mode 100644 src/app/sections/shop-details/shop-details.component.html delete mode 100644 src/app/sections/shop-details/shop-details.component.ts delete mode 100644 src/app/sections/shop-details/shop-details.module.ts diff --git a/package-lock.json b/package-lock.json index 9c232b0e..fa164eb4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -29,7 +29,7 @@ "@vality/dominant-cache-proto": "2.0.0", "@vality/fistful-proto": "2.0.1-ed97a0e.0", "@vality/magista-proto": "2.0.2-37b81e6.0", - "@vality/ng-core": "16.2.1-pr-40-adb1f52.0", + "@vality/ng-core": "16.2.1-pr-40-bdc62db.0", "@vality/payout-manager-proto": "2.0.0", "@vality/repairer-proto": "2.0.2-f5e3b7a.0", "@vality/thrift-ts": "2.4.1-8ad5123.0", @@ -6000,9 +6000,9 @@ "integrity": "sha512-gJizpTWuB74L+XuJ+dUaxAwJDkycdnuVwrXWIl/NKcS7++/zgrgTpw+tM5/Te3rWqkkCnSxC1SK0C4aPbbtifg==" }, "node_modules/@vality/ng-core": { - "version": "16.2.1-pr-40-adb1f52.0", - "resolved": "https://registry.npmjs.org/@vality/ng-core/-/ng-core-16.2.1-pr-40-adb1f52.0.tgz", - "integrity": "sha512-dePHY8wWDE/lDthKkSibBrBQHTAbs1G8nHFiAnAR3Ntt6MOuWcti2qy9i9AxQ9nSN6o7yTzqS8S+GcbaVUYnpA==", + "version": "16.2.1-pr-40-bdc62db.0", + "resolved": "https://registry.npmjs.org/@vality/ng-core/-/ng-core-16.2.1-pr-40-bdc62db.0.tgz", + "integrity": "sha512-hw7ljBUP1X1WYt6ZEQZ2E+y0Udy7G5pUNWL1wUIMmexaXr5H21NTuRZRgy9u3zfxrYfNnLmmI1XZgLfZry/gkA==", "dependencies": { "@ng-matero/extensions": "^16.0.0", "@s-libs/js-core": "^16.0.0", diff --git a/package.json b/package.json index bfa23748..5fec82bb 100644 --- a/package.json +++ b/package.json @@ -37,7 +37,7 @@ "@vality/dominant-cache-proto": "2.0.0", "@vality/fistful-proto": "2.0.1-ed97a0e.0", "@vality/magista-proto": "2.0.2-37b81e6.0", - "@vality/ng-core": "16.2.1-pr-40-adb1f52.0", + "@vality/ng-core": "16.2.1-pr-40-bdc62db.0", "@vality/payout-manager-proto": "2.0.0", "@vality/repairer-proto": "2.0.2-f5e3b7a.0", "@vality/thrift-ts": "2.4.1-8ad5123.0", diff --git a/src/app/sections/party-shops/party-shops.component.html b/src/app/sections/party-shops/party-shops.component.html index a4d2acd7..93df1d2e 100644 --- a/src/app/sections/party-shops/party-shops.component.html +++ b/src/app/sections/party-shops/party-shops.component.html @@ -1,4 +1,26 @@
Merchant's shops
- +
+ + + + + + +
+ + + + + + + diff --git a/src/app/sections/party-shops/party-shops.component.ts b/src/app/sections/party-shops/party-shops.component.ts index 60bdc4dd..f53902fe 100644 --- a/src/app/sections/party-shops/party-shops.component.ts +++ b/src/app/sections/party-shops/party-shops.component.ts @@ -1,4 +1,24 @@ -import { ChangeDetectionStrategy, Component } from '@angular/core'; +import { ChangeDetectionStrategy, Component, TemplateRef, ViewChild } from '@angular/core'; +import { FormControl } from '@angular/forms'; +import { ActivatedRoute } from '@angular/router'; +import { Shop } from '@vality/domain-proto/domain'; +import { + Column, + ConfirmDialogComponent, + createOperationColumn, + DialogResponseStatus, + DialogService, + NotifyLogService, + progressTo, +} from '@vality/ng-core'; +import startCase from 'lodash-es/startCase'; +import { BehaviorSubject, combineLatest, map, switchMap } from 'rxjs'; +import { debounceTime, filter, shareReplay, startWith } from 'rxjs/operators'; +import { Memoize } from 'typescript-memoize'; + +import { PartyManagementService } from '@cc/app/api/payment-processing'; +import { SidenavInfoService } from '@cc/app/shared/components/sidenav-info'; +import { getUnionKey } from '@cc/utils'; import { PartyShopsService } from './party-shops.service'; @@ -8,6 +28,163 @@ import { PartyShopsService } from './party-shops.service'; changeDetection: ChangeDetectionStrategy.OnPush, }) export class PartyShopsComponent { - shops$ = this.partyShopsService.shops$; - constructor(private partyShopsService: PartyShopsService) {} + @ViewChild('shopTpl') shopTpl: TemplateRef; + @ViewChild('contractTpl') contractTpl: TemplateRef; + + filterControl = new FormControl(''); + shops$ = combineLatest([ + this.partyShopsService.shops$, + this.filterControl.valueChanges.pipe( + startWith(this.filterControl.value), + debounceTime(200), + ), + ]).pipe( + map(([shops, searchStr]) => + shops.filter((s) => JSON.stringify(s).toLowerCase().includes(searchStr.toLowerCase())), + ), + shareReplay({ refCount: true, bufferSize: 1 }), + ); + selectedShop?: Shop; + columns: Column[] = [ + { + field: 'details.name', + description: 'id', + pinned: 'left', + click: (d) => { + this.selectedShop = d; + this.sidenavInfoService.toggle(this.shopTpl, d.details.name || `Shop #${d.id}`, d); + }, + }, + { + field: 'contract_id', + header: 'Contract', + click: (d) => { + this.selectedShop = d; + this.sidenavInfoService.toggle(this.contractTpl, `Contract #${d.id}`, d); + }, + }, + { + field: 'details.description', + }, + { + field: 'location.url', + }, + { + field: 'account.currency.symbolic_code', + header: 'Currency', + }, + { + field: 'blocking', + type: 'tag', + formatter: (shop) => getUnionKey(shop.blocking), + typeParameters: { + label: (shop) => startCase(getUnionKey(shop.blocking)), + tags: { + blocked: { color: 'warn' }, + unblocked: { color: 'success' }, + }, + }, + }, + { + field: 'suspension', + type: 'tag', + formatter: (shop) => getUnionKey(shop.suspension), + typeParameters: { + label: (shop) => startCase(getUnionKey(shop.suspension)), + tags: { + suspended: { color: 'warn' }, + active: { color: 'success' }, + }, + }, + }, + createOperationColumn([ + { + label: (shop) => + getUnionKey(shop.suspension) === 'suspended' ? 'Activate' : 'Suspend', + click: (shop) => { + this.toggleSuspension(shop); + }, + }, + { + label: (shop) => (getUnionKey(shop.blocking) === 'blocked' ? 'Unblock' : 'Block'), + click: (shop) => { + this.toggleBlocking(shop); + }, + }, + ]), + ]; + progress$ = new BehaviorSubject(0); + + constructor( + private partyShopsService: PartyShopsService, + private route: ActivatedRoute, + private sidenavInfoService: SidenavInfoService, + private partyManagementService: PartyManagementService, + private dialogService: DialogService, + private log: NotifyLogService, + ) {} + + @Memoize() + getContract(shopID: string) { + return this.partyManagementService + .GetShopContract(this.route.snapshot.params.partyID, shopID) + .pipe( + progressTo(this.progress$), + map((c) => c.contract), + shareReplay({ refCount: true, bufferSize: 1 }), + ); + } + + toggleBlocking(shop: Shop) { + const partyID = this.route.snapshot.params.partyID; + this.dialogService + .open(ConfirmDialogComponent, { + title: getUnionKey(shop.blocking) === 'unblocked' ? 'Block shop' : 'Unblock shop', + hasReason: true, + }) + .afterClosed() + .pipe( + filter((r) => r.status === DialogResponseStatus.Success), + switchMap((r) => + getUnionKey(shop.blocking) === 'unblocked' + ? this.partyManagementService.BlockShop(partyID, shop.id, r.data.reason) + : this.partyManagementService.UnblockShop(partyID, shop.id, r.data.reason), + ), + ) + .subscribe({ + next: () => { + this.partyShopsService.reload(); + this.log.success(); + }, + error: (err) => { + this.log.error(err); + }, + }); + } + + toggleSuspension(shop: Shop) { + const partyID = this.route.snapshot.params.partyID; + this.dialogService + .open(ConfirmDialogComponent, { + title: getUnionKey(shop.suspension) === 'active' ? 'Suspend shop' : 'Activate shop', + }) + .afterClosed() + .pipe( + filter((r) => r.status === DialogResponseStatus.Success), + switchMap(() => + getUnionKey(shop.suspension) === 'active' + ? this.partyManagementService.SuspendShop(partyID, shop.id) + : this.partyManagementService.ActivateShop(partyID, shop.id), + ), + ) + .subscribe({ + next: () => { + this.partyShopsService.reload(); + this.log.success(); + }, + error: (err) => { + this.log.error(err); + }, + }); + } } diff --git a/src/app/sections/party-shops/party-shops.module.ts b/src/app/sections/party-shops/party-shops.module.ts index 02661392..80f75a2e 100644 --- a/src/app/sections/party-shops/party-shops.module.ts +++ b/src/app/sections/party-shops/party-shops.module.ts @@ -1,33 +1,26 @@ import { CommonModule } from '@angular/common'; import { NgModule } from '@angular/core'; import { FlexModule } from '@angular/flex-layout'; -import { MatButtonModule } from '@angular/material/button'; +import { ReactiveFormsModule } from '@angular/forms'; import { MatCardModule } from '@angular/material/card'; -import { MatFormFieldModule } from '@angular/material/form-field'; -import { MatIconModule } from '@angular/material/icon'; -import { MatInputModule } from '@angular/material/input'; -import { MatMenuModule } from '@angular/material/menu'; -import { MatPaginatorModule } from '@angular/material/paginator'; -import { MatTableModule } from '@angular/material/table'; +import { InputFieldModule, TableModule } from '@vality/ng-core'; + +import { DomainThriftViewerComponent } from '@cc/app/shared/components/thrift-api-crud'; import { PartyShopsRoutingModule } from './party-shops-routing.module'; import { PartyShopsComponent } from './party-shops.component'; -import { ShopsTableComponent } from './shops-table/shops-table.component'; @NgModule({ imports: [ PartyShopsRoutingModule, CommonModule, FlexModule, - MatPaginatorModule, - MatTableModule, - MatFormFieldModule, - MatInputModule, - MatButtonModule, MatCardModule, - MatIconModule, - MatMenuModule, + TableModule, + ReactiveFormsModule, + InputFieldModule, + DomainThriftViewerComponent, ], - declarations: [PartyShopsComponent, ShopsTableComponent], + declarations: [PartyShopsComponent], }) export class PartyShopsModule {} diff --git a/src/app/sections/party-shops/party-shops.service.ts b/src/app/sections/party-shops/party-shops.service.ts index 2dc7d761..d41ac330 100644 --- a/src/app/sections/party-shops/party-shops.service.ts +++ b/src/app/sections/party-shops/party-shops.service.ts @@ -1,20 +1,25 @@ import { Injectable } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; import { Party } from '@vality/domain-proto/domain'; -import { defer, Observable } from 'rxjs'; -import { map, pluck, shareReplay, switchMap } from 'rxjs/operators'; +import { defer, merge, Observable, Subject } from 'rxjs'; +import { map, shareReplay, switchMap } from 'rxjs/operators'; import { PartyManagementService } from '@cc/app/api/payment-processing'; @Injectable() export class PartyShopsService { shops$ = defer(() => this.party$).pipe( - pluck('shops'), + map((p) => p.shops), map((shops) => Array.from(shops.values())), ); - private party$: Observable = this.route.params.pipe( - pluck('partyID'), + private reload$ = new Subject(); + + private party$: Observable = merge( + this.route.params, + this.reload$.pipe(map(() => this.route.snapshot.params)), + ).pipe( + map((p) => p.partyID), switchMap((partyID) => this.partyManagementService.Get(partyID)), shareReplay(1), ); @@ -23,4 +28,8 @@ export class PartyShopsService { private partyManagementService: PartyManagementService, private route: ActivatedRoute, ) {} + + reload() { + this.reload$.next(); + } } diff --git a/src/app/sections/party-shops/shops-table/shops-table.component.html b/src/app/sections/party-shops/shops-table/shops-table.component.html deleted file mode 100644 index 8ac777b6..00000000 --- a/src/app/sections/party-shops/shops-table/shops-table.component.html +++ /dev/null @@ -1,51 +0,0 @@ -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Shop ID{{ shop.id }}Name{{ shop.details.name }}Url{{ shop.location.url }} - - - - -
- - -
-
-
diff --git a/src/app/sections/party-shops/shops-table/shops-table.component.scss b/src/app/sections/party-shops/shops-table/shops-table.component.scss deleted file mode 100644 index ef4e1af9..00000000 --- a/src/app/sections/party-shops/shops-table/shops-table.component.scss +++ /dev/null @@ -1,11 +0,0 @@ -table { - width: 100%; -} - -.action-cell { - width: 8px; -} - -table { - width: 100%; -} diff --git a/src/app/sections/party-shops/shops-table/shops-table.component.ts b/src/app/sections/party-shops/shops-table/shops-table.component.ts deleted file mode 100644 index 4204581b..00000000 --- a/src/app/sections/party-shops/shops-table/shops-table.component.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { Component, Input, OnChanges, SimpleChanges, ViewChild } from '@angular/core'; -import { MatPaginator } from '@angular/material/paginator'; -import { MatTableDataSource } from '@angular/material/table'; -import { ActivatedRoute, Router } from '@angular/router'; -import { Shop } from '@vality/domain-proto/domain'; -import { pluck } from 'rxjs/operators'; - -@Component({ - selector: 'cc-shops-table', - templateUrl: 'shops-table.component.html', - styleUrls: ['shops-table.component.scss'], -}) -export class ShopsTableComponent implements OnChanges { - @Input() shops: Shop[]; - @ViewChild(MatPaginator, { static: true }) paginator: MatPaginator; - - dataSource: MatTableDataSource = new MatTableDataSource(); - displayedColumns = ['id', 'name', 'url', 'actions']; - - constructor( - private router: Router, - private route: ActivatedRoute, - ) {} - - ngOnChanges({ shops }: SimpleChanges) { - if (shops.currentValue) { - this.dataSource.data = shops.currentValue; - this.dataSource.filterPredicate = (shop: Shop, filter: string) => - JSON.stringify(shop).toLowerCase().includes(filter); - this.dataSource.paginator = this.paginator; - } - } - - applyFilter(filterValue: string) { - this.dataSource.filter = filterValue.trim().toLowerCase(); - } - - navigateToShop(shopID: string) { - this.route.params.pipe(pluck('partyID')).subscribe((partyID: string) => { - void this.router.navigate([`/party/${partyID}/shop/${shopID}`]); - }); - } -} diff --git a/src/app/sections/party/party-routing.module.ts b/src/app/sections/party/party-routing.module.ts index f11a0c74..a446f922 100644 --- a/src/app/sections/party/party-routing.module.ts +++ b/src/app/sections/party/party-routing.module.ts @@ -20,11 +20,6 @@ import { ROUTING_CONFIG } from './routing-config'; loadChildren: () => import('../party-shops').then((m) => m.PartyShopsModule), }, - { - path: 'shop/:shopID', - loadChildren: () => - import('../shop-details').then((m) => m.ShopDetailsModule), - }, { path: 'routing-rules', loadChildren: () => diff --git a/src/app/sections/routing-rules/party-delegate-rulesets/party-delegate-rulesets.component.html b/src/app/sections/routing-rules/party-delegate-rulesets/party-delegate-rulesets.component.html index f75ff580..832e23d2 100644 --- a/src/app/sections/routing-rules/party-delegate-rulesets/party-delegate-rulesets.component.html +++ b/src/app/sections/routing-rules/party-delegate-rulesets/party-delegate-rulesets.component.html @@ -1,19 +1,13 @@ - - - - -
-
-
Party delegate rulesets
- -
- - +
+
+
Party delegate rulesets
+
- + + +
diff --git a/src/app/sections/routing-rules/party-delegate-rulesets/party-delegate-rulesets.component.ts b/src/app/sections/routing-rules/party-delegate-rulesets/party-delegate-rulesets.component.ts index e64e5603..52729424 100644 --- a/src/app/sections/routing-rules/party-delegate-rulesets/party-delegate-rulesets.component.ts +++ b/src/app/sections/routing-rules/party-delegate-rulesets/party-delegate-rulesets.component.ts @@ -23,9 +23,9 @@ import { PartyDelegateRulesetsService } from './party-delegate-rulesets.service' }) export class PartyDelegateRulesetsComponent { displayedColumns = [ + { key: 'partyDelegate', name: 'Party delegate' }, { key: 'paymentInstitution', name: 'Payment institution' }, { key: 'mainRuleset', name: 'Main ruleset' }, - { key: 'partyDelegate', name: 'Party delegate' }, ]; isLoading$ = this.domainStoreService.isLoading$; data$ = this.partyDelegateRulesetsService.getDelegatesWithPaymentInstitution().pipe( diff --git a/src/app/sections/routing-rules/party-routing-ruleset/party-routing-ruleset.component.html b/src/app/sections/routing-rules/party-routing-ruleset/party-routing-ruleset.component.html index f5e28b0a..1b538fde 100644 --- a/src/app/sections/routing-rules/party-routing-ruleset/party-routing-ruleset.component.html +++ b/src/app/sections/routing-rules/party-routing-ruleset/party-routing-ruleset.component.html @@ -5,7 +5,7 @@
!!r), map(([ruleset, shops]) => ruleset.data.decisions.delegates @@ -63,7 +66,7 @@ export class PartyRoutingRulesetComponent { ); walletsData$ = combineLatest([ this.partyRuleset$, - this.partyRoutingRulesetService.wallets$, + this.partyRoutingRulesetService.wallets$.pipe(startWith([])), ]).pipe( filter(([r]) => !!r), map(([ruleset, wallets]) => diff --git a/src/app/sections/routing-rules/routing-rules-list/routing-rules-list.component.html b/src/app/sections/routing-rules/routing-rules-list/routing-rules-list.component.html index 4cfd1ff4..066b3d53 100644 --- a/src/app/sections/routing-rules/routing-rules-list/routing-rules-list.component.html +++ b/src/app/sections/routing-rules/routing-rules-list/routing-rules-list.component.html @@ -1,70 +1 @@ - - - - - - - - - - - - - -
{{ column.name }} -
-
{{ element[column.key]?.text || ' ' }}
-
- {{ element[column.key]?.caption || ' ' }} -
-
- - {{ element[column.key] }} - -
- - - - - - - - -
- - -
-
- - -
- Routing rules not found -
-
+ diff --git a/src/app/sections/routing-rules/routing-rules-list/routing-rules-list.component.spec.ts b/src/app/sections/routing-rules/routing-rules-list/routing-rules-list.component.spec.ts deleted file mode 100644 index 82728a87..00000000 --- a/src/app/sections/routing-rules/routing-rules-list/routing-rules-list.component.spec.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { Component, DebugElement } from '@angular/core'; -import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { By } from '@angular/platform-browser'; - -import { RoutingRulesListComponent } from './routing-rules-list.component'; - -@Component({ - selector: 'cc-host', - template: ``, -}) -class HostComponent {} - -describe('RoutingRulesListComponent', () => { - let fixture: ComponentFixture; - let debugElement: DebugElement; - let component: RoutingRulesListComponent; - - beforeEach(async () => { - await TestBed.configureTestingModule({ - imports: [], - declarations: [HostComponent, RoutingRulesListComponent], - }).compileComponents(); - - fixture = TestBed.createComponent(HostComponent); - debugElement = fixture.debugElement.query(By.directive(RoutingRulesListComponent)); - component = debugElement.componentInstance; - - fixture.detectChanges(); - }); - - it('should be created', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/src/app/sections/routing-rules/routing-rules-list/routing-rules-list.component.ts b/src/app/sections/routing-rules/routing-rules-list/routing-rules-list.component.ts index c0ce2d99..c93e6efc 100644 --- a/src/app/sections/routing-rules/routing-rules-list/routing-rules-list.component.ts +++ b/src/app/sections/routing-rules/routing-rules-list/routing-rules-list.component.ts @@ -4,15 +4,20 @@ import { EventEmitter, Input, Output, - ViewChild, + OnChanges, } from '@angular/core'; -import { MatPaginator } from '@angular/material/paginator'; -import { MatTableDataSource } from '@angular/material/table'; import { ActivatedRoute } from '@angular/router'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; -import { DialogResponseStatus, DialogService, ConfirmDialogComponent } from '@vality/ng-core'; -import { combineLatest, defer, ReplaySubject } from 'rxjs'; -import { filter, map, shareReplay, startWith, switchMap } from 'rxjs/operators'; +import { + DialogResponseStatus, + DialogService, + ConfirmDialogComponent, + Column, + createOperationColumn, + ComponentChanges, +} from '@vality/ng-core'; +import { coerceBoolean } from 'coerce-property'; +import { filter, switchMap } from 'rxjs/operators'; import { NotificationErrorService } from '@cc/app/shared/services/notification-error'; @@ -36,47 +41,15 @@ export class RoutingRulesListComponent< T extends { [N in PropertyKey]: unknown } & DelegateId = { [N in PropertyKey]: unknown; } & DelegateId, -> { +> implements OnChanges +{ + @Input() data: T[]; @Input() displayedColumns: { key: keyof T; name: string }[]; - - @Input() set data(data: T[]) { - this.data$.next(data); - } + @Input() @coerceBoolean progress: boolean | '' = false; @Output() toDetails = new EventEmitter(); - @ViewChild(MatPaginator) set paginator(paginator: MatPaginator) { - this.paginator$.next(paginator); - } - - dataSource$ = combineLatest([ - defer(() => this.data$), - defer(() => this.paginator$).pipe(startWith(null)), - ]).pipe( - map(([d, paginator]) => { - const data = new MatTableDataSource(d); - data.paginator = paginator; - return data; - }), - shareReplay(1), - ); - - get allDisplayedColumns() { - if (!this.displayedColumns) { - return []; - } - return this.displayedColumns - .concat([ - { - key: 'actions', - name: 'Actions', - }, - ]) - .map(({ key }) => key); - } - - private data$ = new ReplaySubject(1); - private paginator$ = new ReplaySubject(1); + columns: Column[] = []; constructor( private dialogService: DialogService, @@ -85,6 +58,61 @@ export class RoutingRulesListComponent< private route: ActivatedRoute, ) {} + ngOnChanges(changes: ComponentChanges>) { + if (changes.displayedColumns) { + this.columns = [ + ...this.displayedColumns.map( + (c, idx): Column => ({ + field: `${c.key as string}.text`, + formatter: + idx === 0 + ? (d) => { + const v = d?.[c.key] as { caption: string; text: string }; + return v?.text || `#${v?.caption}`; + } + : undefined, + click: + idx === 0 + ? (d) => + this.toDetails.emit({ + parentRefId: d?.parentRefId, + delegateIdx: d?.delegateIdx, + }) + : undefined, + header: c.name, + description: `${c.key as string}.caption`, + }), + ), + createOperationColumn([ + { + label: 'Details', + click: (d) => + this.toDetails.emit({ + parentRefId: d?.parentRefId, + delegateIdx: d?.delegateIdx, + }), + }, + { + label: 'Change delegate ruleset', + click: (d) => this.changeDelegateRuleset(d), + }, + { + label: 'Change main ruleset', + click: (d) => this.changeTarget(d), + }, + { + label: 'Clone delegate ruleset', + click: (d) => this.cloneDelegateRuleset(d), + }, + { + label: 'Delete', + click: (d) => this.delete(d), + }, + ]), + ]; + } + } + changeDelegateRuleset(delegateId: DelegateId) { this.dialogService .open(ChangeDelegateRulesetDialogComponent, { diff --git a/src/app/sections/routing-rules/routing-rules-list/routing-rules-list.module.ts b/src/app/sections/routing-rules/routing-rules-list/routing-rules-list.module.ts index b5d68659..45049b12 100644 --- a/src/app/sections/routing-rules/routing-rules-list/routing-rules-list.module.ts +++ b/src/app/sections/routing-rules/routing-rules-list/routing-rules-list.module.ts @@ -6,7 +6,7 @@ import { MatCardModule } from '@angular/material/card'; import { MatIconModule } from '@angular/material/icon'; import { MatMenuModule } from '@angular/material/menu'; import { MatPaginatorModule } from '@angular/material/paginator'; -import { MatTableModule } from '@angular/material/table'; +import { TableModule } from '@vality/ng-core'; import { RoutingRulesListComponent } from './routing-rules-list.component'; @@ -15,12 +15,11 @@ import { RoutingRulesListComponent } from './routing-rules-list.component'; CommonModule, MatMenuModule, MatCardModule, - MatTableModule, MatPaginatorModule, - MatTableModule, MatIconModule, FlexLayoutModule, MatButtonModule, + TableModule, ], declarations: [RoutingRulesListComponent], exports: [RoutingRulesListComponent], diff --git a/src/app/sections/routing-rules/routing-ruleset/routing-ruleset.component.ts b/src/app/sections/routing-rules/routing-ruleset/routing-ruleset.component.ts index 58963973..e05220a7 100644 --- a/src/app/sections/routing-rules/routing-ruleset/routing-ruleset.component.ts +++ b/src/app/sections/routing-rules/routing-ruleset/routing-ruleset.component.ts @@ -57,7 +57,7 @@ export class RoutingRulesetComponent { field: 'candidate', description: 'description', sortable: true, - formatter: (d) => this.getCandidateIdx(d).pipe(map((idx) => `${idx + 1}`)), + formatter: (d) => this.getCandidateIdx(d).pipe(map((idx) => `#${idx + 1}`)), click: (d) => { this.getCandidateIdx(d) .pipe(untilDestroyed(this)) @@ -129,6 +129,16 @@ export class RoutingRulesetComponent { }); }, }, + { + label: 'Duplicate', + click: (d) => { + this.getCandidateIdx(d) + .pipe(untilDestroyed(this)) + .subscribe((idx) => { + void this.duplicateShopRule(idx); + }); + }, + }, { label: 'Remove', click: (d) => { @@ -176,7 +186,7 @@ export class RoutingRulesetComponent { next: (res) => { if (res.status === DialogResponseStatus.Success) { this.domainStoreService.forceReload(); - this.log.successOperation('update', 'Routing rule'); + this.log.successOperation('create', 'Routing rule'); } }, error: (err) => { @@ -217,6 +227,38 @@ export class RoutingRulesetComponent { }); } + duplicateShopRule(idx: number) { + this.routingRulesetService.refID$ + .pipe( + first(), + switchMap((refId) => this.routingRulesService.getShopCandidate(refId, idx)), + withLatestFrom(this.routingRulesetService.refID$), + switchMap(([shopCandidate, refId]) => + this.dialog + .open(DomainThriftFormDialogComponent, { + type: 'RoutingCandidate', + title: 'Add shop routing candidate', + object: shopCandidate, + actionType: 'create', + action: (params) => this.routingRulesService.addShopRule(refId, params), + }) + .afterClosed(), + ), + ) + .pipe(untilDestroyed(this)) + .subscribe({ + next: (res) => { + if (res.status === DialogResponseStatus.Success) { + this.domainStoreService.forceReload(); + this.log.successOperation('create', 'Routing rule'); + } + }, + error: (err) => { + this.log.error(err); + }, + }); + } + removeShopRule(idx: number) { this.routingRulesetService.removeShopRule(idx); } diff --git a/src/app/sections/search-parties/parties-table/index.ts b/src/app/sections/search-parties/parties-table/index.ts deleted file mode 100644 index 7ba71b64..00000000 --- a/src/app/sections/search-parties/parties-table/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './parties-table.module'; diff --git a/src/app/sections/search-parties/parties-table/parties-table.component.html b/src/app/sections/search-parties/parties-table/parties-table.component.html deleted file mode 100644 index 68782612..00000000 --- a/src/app/sections/search-parties/parties-table/parties-table.component.html +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - - - - - - - - - - - - -
Email - {{ party.email }} - ID - {{ party.id }} - - - - - -
diff --git a/src/app/sections/search-parties/parties-table/parties-table.component.scss b/src/app/sections/search-parties/parties-table/parties-table.component.scss deleted file mode 100644 index f7335e41..00000000 --- a/src/app/sections/search-parties/parties-table/parties-table.component.scss +++ /dev/null @@ -1,7 +0,0 @@ -table { - width: 100%; -} - -.action-cell { - width: 8px; -} diff --git a/src/app/sections/search-parties/parties-table/parties-table.component.ts b/src/app/sections/search-parties/parties-table/parties-table.component.ts deleted file mode 100644 index c064c88e..00000000 --- a/src/app/sections/search-parties/parties-table/parties-table.component.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output } from '@angular/core'; -import { Party, PartyID } from '@vality/domain-proto/domain'; - -import { PartyActions } from './party-actions'; -import { PartyMenuItemEvent } from './party-menu-item-event'; - -@Component({ - selector: 'cc-parties-table', - templateUrl: 'parties-table.component.html', - styleUrls: ['parties-table.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class PartiesTableComponent { - @Input() - parties: Party[]; - - @Output() - menuItemSelected$: EventEmitter = new EventEmitter(); - - partyActions = Object.keys(PartyActions); - displayedColumns = ['email', 'id', 'actions']; - - menuItemSelected(action: string, partyID: PartyID): void { - switch (action) { - case PartyActions.NavigateToParty: - this.menuItemSelected$.emit({ action, partyID }); - break; - default: - console.error('Wrong party action type.'); - } - } -} diff --git a/src/app/sections/search-parties/parties-table/parties-table.module.ts b/src/app/sections/search-parties/parties-table/parties-table.module.ts deleted file mode 100644 index 48df3c8e..00000000 --- a/src/app/sections/search-parties/parties-table/parties-table.module.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { CommonModule } from '@angular/common'; -import { NgModule } from '@angular/core'; -import { MatButtonModule } from '@angular/material/button'; -import { MatIconModule } from '@angular/material/icon'; -import { MatMenuModule } from '@angular/material/menu'; -import { MatTableModule } from '@angular/material/table'; - -import { PartiesTableComponent } from './parties-table.component'; -import { PartyActionsPipe } from './party-actions.pipe'; - -@NgModule({ - exports: [PartiesTableComponent], - declarations: [PartiesTableComponent, PartyActionsPipe], - imports: [MatTableModule, MatMenuModule, MatButtonModule, MatIconModule, CommonModule], -}) -export class PartiesTableModule {} diff --git a/src/app/sections/search-parties/parties-table/party-actions.pipe.ts b/src/app/sections/search-parties/parties-table/party-actions.pipe.ts deleted file mode 100644 index 6d0a83d2..00000000 --- a/src/app/sections/search-parties/parties-table/party-actions.pipe.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { Pipe, PipeTransform } from '@angular/core'; - -import { PartyActions } from './party-actions'; - -const PARTY_ACTION_NAMES: { [N in PartyActions]: string } = { - [PartyActions.NavigateToParty]: 'Merchant details', -}; - -@Pipe({ - name: 'ccPartyActions', -}) -export class PartyActionsPipe implements PipeTransform { - transform(action: string): string { - return PARTY_ACTION_NAMES[action] || action; - } -} diff --git a/src/app/sections/search-parties/parties-table/party-actions.ts b/src/app/sections/search-parties/parties-table/party-actions.ts deleted file mode 100644 index 31b8ebb2..00000000 --- a/src/app/sections/search-parties/parties-table/party-actions.ts +++ /dev/null @@ -1,3 +0,0 @@ -export enum PartyActions { - NavigateToParty = 'NavigateToParty', -} diff --git a/src/app/sections/search-parties/parties-table/party-menu-item-event.ts b/src/app/sections/search-parties/parties-table/party-menu-item-event.ts deleted file mode 100644 index cd1895d3..00000000 --- a/src/app/sections/search-parties/parties-table/party-menu-item-event.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { PartyID } from '@vality/domain-proto/domain'; - -import { PartyActions } from './party-actions'; - -export interface PartyMenuItemEvent { - action: PartyActions; - partyID: PartyID; -} diff --git a/src/app/sections/search-parties/search-parties.component.html b/src/app/sections/search-parties/search-parties.component.html index 42d97896..13d440ee 100644 --- a/src/app/sections/search-parties/search-parties.component.html +++ b/src/app/sections/search-parties/search-parties.component.html @@ -6,18 +6,12 @@ (searchParamsChanged$)="searchParamsUpdated($event)" > - - - - - - - - - + diff --git a/src/app/sections/search-parties/search-parties.component.ts b/src/app/sections/search-parties/search-parties.component.ts index b5956ed8..68a67d02 100644 --- a/src/app/sections/search-parties/search-parties.component.ts +++ b/src/app/sections/search-parties/search-parties.component.ts @@ -1,11 +1,14 @@ import { Component } from '@angular/core'; import { Router } from '@angular/router'; +import { Party } from '@vality/deanonimus-proto/deanonimus'; +import { Column, createOperationColumn } from '@vality/ng-core'; +import startCase from 'lodash-es/startCase'; import { FetchPartiesService } from '@cc/app/shared/services/fetch-parties.service'; +import { getUnionKey } from '../../../utils'; + import { PartiesSearchFiltersParams } from './parties-search-filters'; -import { PartyActions } from './parties-table/party-actions'; -import { PartyMenuItemEvent } from './parties-table/party-menu-item-event'; import { SearchPartiesService } from './search-parties.service'; @Component({ @@ -17,6 +20,50 @@ export class SearchPartiesComponent { initSearchParams$ = this.partiesService.data$; inProgress$ = this.fetchPartiesService.inProgress$; parties$ = this.fetchPartiesService.parties$; + columns: Column[] = [ + { + field: 'email', + description: 'id', + pinned: 'left', + link: (party) => `/party/${party.id}`, + }, + { + field: 'blocking', + type: 'tag', + formatter: (party) => getUnionKey(party.blocking), + typeParameters: { + label: (party) => startCase(getUnionKey(party.blocking)), + tags: { + blocked: { color: 'warn' }, + unblocked: { color: 'success' }, + }, + }, + }, + { + field: 'suspension', + type: 'tag', + formatter: (party) => getUnionKey(party.suspension), + typeParameters: { + label: (party) => startCase(getUnionKey(party.suspension)), + tags: { + suspended: { color: 'warn' }, + active: { color: 'success' }, + }, + }, + }, + { + field: 'shops', + formatter: (party) => party.shops.size, + }, + createOperationColumn([ + { + label: 'Details', + click: (party) => { + this.router.navigate([`/party/${party.id}`]); + }, + }, + ]), + ]; constructor( private partiesService: SearchPartiesService, @@ -28,11 +75,4 @@ export class SearchPartiesComponent { this.partiesService.preserve($event); this.fetchPartiesService.searchParties($event.text); } - - partyMenuItemSelected(event: PartyMenuItemEvent) { - switch (event.action) { - case PartyActions.NavigateToParty: - void this.router.navigate([`/party/${event.partyID}`]); - } - } } diff --git a/src/app/sections/search-parties/search-parties.module.ts b/src/app/sections/search-parties/search-parties.module.ts index b771589e..28039c3a 100644 --- a/src/app/sections/search-parties/search-parties.module.ts +++ b/src/app/sections/search-parties/search-parties.module.ts @@ -3,13 +3,13 @@ import { NgModule } from '@angular/core'; import { FlexModule } from '@angular/flex-layout'; import { MatCardModule } from '@angular/material/card'; import { MatProgressBarModule } from '@angular/material/progress-bar'; +import { TableModule } from '@vality/ng-core'; import { EmptySearchResultModule } from '@cc/components/empty-search-result'; import { PageLayoutModule } from '../../shared'; import { PartiesSearchFiltersModule } from './parties-search-filters'; -import { PartiesTableModule } from './parties-table'; import { SearchPartiesRoutingModule } from './search-parties-routing.module'; import { SearchPartiesComponent } from './search-parties.component'; @@ -19,11 +19,11 @@ import { SearchPartiesComponent } from './search-parties.component'; FlexModule, MatCardModule, PartiesSearchFiltersModule, - PartiesTableModule, CommonModule, EmptySearchResultModule, MatProgressBarModule, PageLayoutModule, + TableModule, ], declarations: [SearchPartiesComponent], }) diff --git a/src/app/sections/shop-details/index.ts b/src/app/sections/shop-details/index.ts deleted file mode 100644 index 74e4f677..00000000 --- a/src/app/sections/shop-details/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './shop-details.module'; diff --git a/src/app/sections/shop-details/routing-config.ts b/src/app/sections/shop-details/routing-config.ts deleted file mode 100644 index d558ec12..00000000 --- a/src/app/sections/shop-details/routing-config.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { Services, RoutingConfig } from '@cc/app/shared/services'; - -export const ROUTING_CONFIG: RoutingConfig = { - services: [Services.PartyManagement], -}; diff --git a/src/app/sections/shop-details/services/fetch-shop.service.ts b/src/app/sections/shop-details/services/fetch-shop.service.ts deleted file mode 100644 index fe5abef3..00000000 --- a/src/app/sections/shop-details/services/fetch-shop.service.ts +++ /dev/null @@ -1,61 +0,0 @@ -import { Injectable } from '@angular/core'; -import { Shop } from '@vality/domain-proto/domain'; -import { PartyID, ShopID } from '@vality/domain-proto/payment_processing'; -import { BehaviorSubject, Observable, defer, EMPTY, merge } from 'rxjs'; -import { catchError, shareReplay, switchMap } from 'rxjs/operators'; - -import { PartyManagementService } from '@cc/app/api/payment-processing'; -import { NotificationErrorService } from '@cc/app/shared/services/notification-error'; -import { inProgressFrom, progressTo } from '@cc/utils'; - -@Injectable() -export class FetchShopService { - shop$: Observable = defer(() => this.getShop$).pipe( - switchMap(({ partyID, shopID }) => - this.partyManagementService.GetShop(partyID, shopID).pipe( - progressTo(this.progress$), - catchError((err) => { - this.notificationErrorService.error( - err, - 'An error occurred while fetching shop', - ); - return EMPTY; - }), - ), - ), - shareReplay({ refCount: true, bufferSize: 1 }), - ); - contract$ = defer(() => this.getShop$).pipe( - switchMap(({ partyID, shopID }) => - this.partyManagementService.GetShopContract(partyID, shopID).pipe( - progressTo(this.progress$), - catchError((err) => { - this.notificationErrorService.error( - err, - 'An error occurred while fetching shop contract', - ); - return EMPTY; - }), - ), - ), - shareReplay({ refCount: true, bufferSize: 1 }), - ); - - inProgress$ = inProgressFrom(() => this.progress$, merge(this.shop$, this.contract$)); - - private getShop$ = new BehaviorSubject<{ partyID: PartyID; shopID: ShopID }>(null); - private progress$ = new BehaviorSubject(0); - - constructor( - private partyManagementService: PartyManagementService, - private notificationErrorService: NotificationErrorService, - ) {} - - getShop(partyID: PartyID, shopID: ShopID) { - this.getShop$.next({ shopID, partyID }); - } - - reload() { - if (this.getShop$.value) this.getShop$.next(this.getShop$.value); - } -} diff --git a/src/app/sections/shop-details/shop-details-routing.module.ts b/src/app/sections/shop-details/shop-details-routing.module.ts deleted file mode 100644 index a4ce02f0..00000000 --- a/src/app/sections/shop-details/shop-details-routing.module.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { NgModule } from '@angular/core'; -import { RouterModule } from '@angular/router'; - -import { AppAuthGuardService } from '@cc/app/shared/services'; - -import { ROUTING_CONFIG } from './routing-config'; -import { ShopDetailsComponent } from './shop-details.component'; - -@NgModule({ - imports: [ - RouterModule.forChild([ - { - path: '', - component: ShopDetailsComponent, - canActivate: [AppAuthGuardService], - data: ROUTING_CONFIG, - }, - ]), - ], -}) -export class ShopDetailsRoutingModule {} diff --git a/src/app/sections/shop-details/shop-details.component.html b/src/app/sections/shop-details/shop-details.component.html deleted file mode 100644 index 99db238b..00000000 --- a/src/app/sections/shop-details/shop-details.component.html +++ /dev/null @@ -1,42 +0,0 @@ -
- Shop details - - - -
- -
-
-
- - Contract - - -
- -
-
-
- - - - -
diff --git a/src/app/sections/shop-details/shop-details.component.ts b/src/app/sections/shop-details/shop-details.component.ts deleted file mode 100644 index 53d3ce35..00000000 --- a/src/app/sections/shop-details/shop-details.component.ts +++ /dev/null @@ -1,112 +0,0 @@ -import { Component } from '@angular/core'; -import { ActivatedRoute } from '@angular/router'; -import { UntilDestroy } from '@ngneat/until-destroy'; -import { DialogService, DialogResponseStatus, ConfirmDialogComponent } from '@vality/ng-core'; -import { combineLatest, switchMap, from } from 'rxjs'; -import { pluck, filter, withLatestFrom, first, map } from 'rxjs/operators'; - -import { DomainMetadataViewExtensionsService } from '@cc/app/shared/components/thrift-api-crud/domain/domain-thrift-viewer/services/domain-metadata-view-extensions'; -import { NotificationErrorService } from '@cc/app/shared/services/notification-error'; - -import { getUnionKey } from '../../../utils'; -import { PartyManagementService } from '../../api/payment-processing'; -import { NotificationService } from '../../shared/services/notification'; - -import { FetchShopService } from './services/fetch-shop.service'; - -@UntilDestroy() -@Component({ - templateUrl: 'shop-details.component.html', - providers: [FetchShopService], -}) -export class ShopDetailsComponent { - partyID$ = this.route.params.pipe(pluck('partyID')); - shopID$ = this.route.params.pipe(pluck('shopID')); - - shop$ = this.fetchShopService.shop$; - contract$ = this.fetchShopService.contract$.pipe(map((c) => c?.contract)); - inProgress$ = this.fetchShopService.inProgress$; - metadata$ = from(import('@vality/domain-proto/metadata.json').then((m) => m.default)); - extensions$ = this.domainMetadataViewExtensionsService.extensions$; - - constructor( - private fetchShopService: FetchShopService, - private route: ActivatedRoute, - private partyManagementService: PartyManagementService, - private dialogService: DialogService, - private notificationErrorService: NotificationErrorService, - private notificationService: NotificationService, - private domainMetadataViewExtensionsService: DomainMetadataViewExtensionsService, - ) { - combineLatest([this.partyID$, this.shopID$]).subscribe(([partyID, shopID]) => { - this.fetchShopService.getShop(partyID, shopID); - }); - } - - toggleBlocking() { - this.shop$ - .pipe( - first(), - switchMap((shop) => - this.dialogService - .open(ConfirmDialogComponent, { - title: - getUnionKey(shop.blocking) === 'unblocked' - ? 'Block shop' - : 'Unblock shop', - hasReason: true, - }) - .afterClosed(), - ), - filter((r) => r.status === DialogResponseStatus.Success), - withLatestFrom(this.shop$, this.partyID$), - switchMap(([{ data }, shop, partyID]) => - getUnionKey(shop.blocking) === 'unblocked' - ? this.partyManagementService.BlockShop(partyID, shop.id, data.reason) - : this.partyManagementService.UnblockShop(partyID, shop.id, data.reason), - ), - ) - .subscribe({ - next: () => { - this.fetchShopService.reload(); - this.notificationService.success(); - }, - error: (err) => { - this.notificationErrorService.error(err); - }, - }); - } - - toggleSuspension() { - this.shop$ - .pipe( - first(), - switchMap((shop) => - this.dialogService - .open(ConfirmDialogComponent, { - title: - getUnionKey(shop.suspension) === 'active' - ? 'Suspend shop' - : 'Activate shop', - }) - .afterClosed(), - ), - filter((r) => r.status === DialogResponseStatus.Success), - withLatestFrom(this.shop$, this.partyID$), - switchMap(([, shop, partyID]) => - getUnionKey(shop.suspension) === 'active' - ? this.partyManagementService.SuspendShop(partyID, shop.id) - : this.partyManagementService.ActivateShop(partyID, shop.id), - ), - ) - .subscribe({ - next: () => { - this.fetchShopService.reload(); - this.notificationService.success(); - }, - error: (err) => { - this.notificationErrorService.error(err); - }, - }); - } -} diff --git a/src/app/sections/shop-details/shop-details.module.ts b/src/app/sections/shop-details/shop-details.module.ts deleted file mode 100644 index fc56a84f..00000000 --- a/src/app/sections/shop-details/shop-details.module.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { CommonModule } from '@angular/common'; -import { NgModule } from '@angular/core'; -import { FlexModule } from '@angular/flex-layout'; -import { MatButtonModule } from '@angular/material/button'; -import { MatCardModule } from '@angular/material/card'; -import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; -import { ActionsModule } from '@vality/ng-core'; - -import { JsonViewerModule } from '@cc/app/shared/components/json-viewer'; -import { HeadlineModule } from '@cc/components/headline'; - -import { ThriftPipesModule } from '../../shared'; - -import { ShopDetailsRoutingModule } from './shop-details-routing.module'; -import { ShopDetailsComponent } from './shop-details.component'; - -@NgModule({ - imports: [ - ShopDetailsRoutingModule, - HeadlineModule, - FlexModule, - MatCardModule, - CommonModule, - MatProgressSpinnerModule, - ActionsModule, - MatButtonModule, - ThriftPipesModule, - JsonViewerModule, - ], - declarations: [ShopDetailsComponent], -}) -export class ShopDetailsModule {} diff --git a/src/app/shared/components/thrift-api-crud/domain/domain-thrift-form-dialog/domain-thrift-form-dialog.component.html b/src/app/shared/components/thrift-api-crud/domain/domain-thrift-form-dialog/domain-thrift-form-dialog.component.html index 90bf4d54..08e0c587 100644 --- a/src/app/shared/components/thrift-api-crud/domain/domain-thrift-form-dialog/domain-thrift-form-dialog.component.html +++ b/src/app/shared/components/thrift-api-crud/domain/domain-thrift-form-dialog/domain-thrift-form-dialog.component.html @@ -1,4 +1,4 @@ - + diff --git a/src/app/shared/components/thrift-api-crud/domain/domain-thrift-form-dialog/domain-thrift-form-dialog.component.ts b/src/app/shared/components/thrift-api-crud/domain/domain-thrift-form-dialog/domain-thrift-form-dialog.component.ts index 4dd7b208..863378ef 100644 --- a/src/app/shared/components/thrift-api-crud/domain/domain-thrift-form-dialog/domain-thrift-form-dialog.component.ts +++ b/src/app/shared/components/thrift-api-crud/domain/domain-thrift-form-dialog/domain-thrift-form-dialog.component.ts @@ -2,7 +2,7 @@ import { Component, Injector } from '@angular/core'; import { FormBuilder, ReactiveFormsModule } from '@angular/forms'; import { MatButtonModule } from '@angular/material/button'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; -import { DialogSuperclass, DialogModule } from '@vality/ng-core'; +import { DialogSuperclass, DialogModule, DEFAULT_DIALOG_CONFIG } from '@vality/ng-core'; import { ValueType } from '@vality/thrift-ts'; import { Observable } from 'rxjs'; @@ -22,13 +22,19 @@ export class DomainThriftFormDialogComponent extends D action: (object: T) => Observable; namespace?: string; object?: T; + actionType?: 'create' | 'update'; }, { object?: T; result?: R; error?: unknown } > { + static defaultDialogConfig = DEFAULT_DIALOG_CONFIG.large; + control = this.fb.control(this.dialogData.object ?? null); - get isUpdate() { - return this.dialogData.object !== undefined; + get actionType() { + return ( + this.dialogData.actionType ?? + (this.dialogData.object !== undefined ? 'update' : 'create') + ); } constructor( diff --git a/src/app/shared/components/thrift-api-crud/domain/domain-thrift-form/domain-thrift-form.component.html b/src/app/shared/components/thrift-api-crud/domain/domain-thrift-form/domain-thrift-form.component.html index de0979f6..c7f8f2ad 100644 --- a/src/app/shared/components/thrift-api-crud/domain/domain-thrift-form/domain-thrift-form.component.html +++ b/src/app/shared/components/thrift-api-crud/domain/domain-thrift-form/domain-thrift-form.component.html @@ -1,7 +1,7 @@ - +> diff --git a/src/app/shared/components/thrift-api-crud/domain/domain-thrift-form/domain-thrift-form.component.ts b/src/app/shared/components/thrift-api-crud/domain/domain-thrift-form/domain-thrift-form.component.ts index 1720dd32..2be009b0 100644 --- a/src/app/shared/components/thrift-api-crud/domain/domain-thrift-form/domain-thrift-form.component.ts +++ b/src/app/shared/components/thrift-api-crud/domain/domain-thrift-form/domain-thrift-form.component.ts @@ -6,6 +6,7 @@ import { createControlProviders, getImportValue } from '@vality/ng-core'; import { DomainMetadataFormExtensionsService } from '../../../../services'; import { MetadataFormModule } from '../../../metadata-form'; +import { ThriftEditorModule } from '../../../thrift-editor'; import { BaseThriftFormSuperclass } from '../../thrift-forms/utils/thrift-form-superclass'; @Component({ @@ -13,7 +14,7 @@ import { BaseThriftFormSuperclass } from '../../thrift-forms/utils/thrift-form-s selector: 'cc-domain-thrift-form', templateUrl: './domain-thrift-form.component.html', providers: createControlProviders(() => DomainThriftFormComponent), - imports: [CommonModule, ReactiveFormsModule, MetadataFormModule], + imports: [CommonModule, ReactiveFormsModule, MetadataFormModule, ThriftEditorModule], }) export class DomainThriftFormComponent extends BaseThriftFormSuperclass { metadata$ = getImportValue(import('@vality/domain-proto/metadata.json')); diff --git a/src/app/shared/components/thrift-api-crud/domain/domain-thrift-viewer/domain-thrift-viewer.component.html b/src/app/shared/components/thrift-api-crud/domain/domain-thrift-viewer/domain-thrift-viewer.component.html index 1e817515..ba8a0c5b 100644 --- a/src/app/shared/components/thrift-api-crud/domain/domain-thrift-viewer/domain-thrift-viewer.component.html +++ b/src/app/shared/components/thrift-api-crud/domain/domain-thrift-viewer/domain-thrift-viewer.component.html @@ -1,6 +1,7 @@ { @Input() value: T; @Input() type: ValueType; + @Input() @coerceBoolean progress: boolean | '' = false; // @Input() extensions?: MetadataViewExtension[]; metadata$ = getImportValue(import('@vality/domain-proto/metadata.json')); diff --git a/src/app/shared/components/thrift-editor/thrift-editor.component.ts b/src/app/shared/components/thrift-editor/thrift-editor.component.ts index 0b9d2eb7..b7122782 100644 --- a/src/app/shared/components/thrift-editor/thrift-editor.component.ts +++ b/src/app/shared/components/thrift-editor/thrift-editor.component.ts @@ -24,7 +24,7 @@ export enum EditorKind { providers: createControlProviders(() => ThriftEditorComponent), }) export class ThriftEditorComponent extends ValidatedFormControlSuperclass { - @Input() kind: EditorKind = EditorKind.Editor; + @Input() kind: EditorKind = EditorKind.Form; @Input() defaultValue?: T; diff --git a/src/app/shared/components/thrift-viewer/thrift-viewer.component.html b/src/app/shared/components/thrift-viewer/thrift-viewer.component.html index 9933f63f..5bd3c51b 100644 --- a/src/app/shared/components/thrift-viewer/thrift-viewer.component.html +++ b/src/app/shared/components/thrift-viewer/thrift-viewer.component.html @@ -1,32 +1,35 @@ -
- - - -
+ +
+ - -
- -
- -
+ > + + + + +
+ +
+
+
+ diff --git a/src/app/shared/components/thrift-viewer/thrift-viewer.component.ts b/src/app/shared/components/thrift-viewer/thrift-viewer.component.ts index 15609534..734bd0e6 100644 --- a/src/app/shared/components/thrift-viewer/thrift-viewer.component.ts +++ b/src/app/shared/components/thrift-viewer/thrift-viewer.component.ts @@ -3,6 +3,7 @@ import { UntilDestroy } from '@ngneat/until-destroy'; import { ThriftAstMetadata } from '@vality/domain-proto'; import { ComponentChanges } from '@vality/ng-core'; import { ValueType } from '@vality/thrift-ts'; +import { coerceBoolean } from 'coerce-property'; import { ReplaySubject } from 'rxjs'; import { MetadataViewExtension } from '@cc/app/shared/components/json-viewer'; @@ -26,6 +27,7 @@ export class ThriftViewerComponent implements OnChanges { @Input() kind: ViewerKind = ViewerKind.Component; @Input() value: T; @Input() compared?: T; + @Input() @coerceBoolean progress: boolean | '' = false; @Input() metadata: ThriftAstMetadata[]; @Input() namespace: string; diff --git a/src/app/shared/components/thrift-viewer/thrift-viewer.module.ts b/src/app/shared/components/thrift-viewer/thrift-viewer.module.ts index eb820e86..041d54f1 100644 --- a/src/app/shared/components/thrift-viewer/thrift-viewer.module.ts +++ b/src/app/shared/components/thrift-viewer/thrift-viewer.module.ts @@ -5,6 +5,7 @@ import { ReactiveFormsModule } from '@angular/forms'; import { MatButtonModule } from '@angular/material/button'; import { MatButtonToggleModule } from '@angular/material/button-toggle'; import { MatIconModule } from '@angular/material/icon'; +import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; import { MetadataFormModule } from '@cc/app/shared/components/metadata-form'; import { MonacoEditorModule } from '@cc/components/monaco-editor'; @@ -27,6 +28,7 @@ import { ThriftViewerComponent } from './thrift-viewer.component'; FlexModule, JsonViewerModule, GridModule, + MatProgressSpinnerModule, ], }) export class ThriftViewerModule {}