mirror of
https://github.com/valitydev/control-center.git
synced 2024-11-06 02:25:17 +00:00
Add change delegate ruleset with refactor (#235)
This commit is contained in:
parent
f3c7bae9c9
commit
9c9b59602f
69
package-lock.json
generated
69
package-lock.json
generated
@ -3760,13 +3760,13 @@
|
||||
}
|
||||
},
|
||||
"@rbkmoney/angular-templates": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://npm.pkg.github.com/download/@rbkmoney/angular-templates/0.1.2/03923ba6c89fd4ba87e9acf77f1074d3693dbcfdc0e775f707d0338b7ad4b997",
|
||||
"integrity": "sha512-io9DKeEbTQ0/h1UVkl18KjqWg3I2BxwHqvbSTpR7xkJ9J4VKqXS92BB1JYpOinQzY8W7qAxVYDosGBazhRIftA==",
|
||||
"version": "0.2.2",
|
||||
"resolved": "https://npm.pkg.github.com/download/@rbkmoney/angular-templates/0.2.2/0cf7c24313ca0e4f6b12ca9d666e0f83dcb3ca373cd95e4b57b9df41087b2f8a",
|
||||
"integrity": "sha512-8QgSANZyXixa2HmwjlSXgppaR9p2NTzfn7Gt5Q6mmP1jHrHCfaN+Cso6e9Z2xth9Wae4BPz/tWYCRSWF0aLfSA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"genry": "^0.15.0",
|
||||
"lodash": "^4.17.15"
|
||||
"genry": "^0.16.0",
|
||||
"lodash": "^4.17.20"
|
||||
}
|
||||
},
|
||||
"@rbkmoney/partial-fetcher": {
|
||||
@ -7669,9 +7669,9 @@
|
||||
}
|
||||
},
|
||||
"easy-stack": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/easy-stack/-/easy-stack-1.0.0.tgz",
|
||||
"integrity": "sha1-EskbMIWjfwuqM26UhurEv5Tj54g=",
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/easy-stack/-/easy-stack-1.0.1.tgz",
|
||||
"integrity": "sha512-wK2sCs4feiiJeFXn3zvY0p41mdU5VUgbgs1rNsc/y5ngFUijdWd+iIN8eoyuZHKB8xN6BL4PdWmzqFmxNg6V2w==",
|
||||
"dev": true
|
||||
},
|
||||
"ecc-jsbn": {
|
||||
@ -8933,9 +8933,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"genry": {
|
||||
"version": "0.15.0",
|
||||
"resolved": "https://registry.npmjs.org/genry/-/genry-0.15.0.tgz",
|
||||
"integrity": "sha512-XWjWNZzeXTKDtGsVyQSS6hnBlBDY/H7wMi0spj3bQv2yZ8+fVZy9M0TaS3W23NvRdNIZWx2iL6WGbLmqDQcNxA==",
|
||||
"version": "0.16.0",
|
||||
"resolved": "https://registry.npmjs.org/genry/-/genry-0.16.0.tgz",
|
||||
"integrity": "sha512-mgRduClrLDBS0JkaiFZBK2mP0ogFydKWIDMGmGOF2dS6YlbHa47ru6ZyYdx9AgUxFmWB1SFGTyahCRcAIK3gvg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"cosmiconfig": "^6.0.0",
|
||||
@ -8944,7 +8944,7 @@
|
||||
"ora": "^4.0.3",
|
||||
"pkg-up": "^3.1.0",
|
||||
"prettier": "^2.0.4",
|
||||
"prompts": "^2.3.2",
|
||||
"prompts": "^2.4.0",
|
||||
"ts-node": "^8.8.2",
|
||||
"yargs": "^15.3.1"
|
||||
},
|
||||
@ -8956,12 +8956,11 @@
|
||||
"dev": true
|
||||
},
|
||||
"ansi-styles": {
|
||||
"version": "4.2.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
|
||||
"integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==",
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
|
||||
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/color-name": "^1.1.1",
|
||||
"color-convert": "^2.0.1"
|
||||
}
|
||||
},
|
||||
@ -9021,9 +9020,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"import-fresh": {
|
||||
"version": "3.2.1",
|
||||
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.1.tgz",
|
||||
"integrity": "sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ==",
|
||||
"version": "3.3.0",
|
||||
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
|
||||
"integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"parent-module": "^1.0.0",
|
||||
@ -10459,18 +10458,18 @@
|
||||
}
|
||||
},
|
||||
"js-message": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/js-message/-/js-message-1.0.5.tgz",
|
||||
"integrity": "sha1-IwDSSxrwjondCVvBpMnJz8uJLRU=",
|
||||
"version": "1.0.7",
|
||||
"resolved": "https://registry.npmjs.org/js-message/-/js-message-1.0.7.tgz",
|
||||
"integrity": "sha512-efJLHhLjIyKRewNS9EGZ4UpI8NguuL6fKkhRxVuMmrGV2xN/0APGdQYwLFky5w9naebSZ0OwAGp0G6/2Cg90rA==",
|
||||
"dev": true
|
||||
},
|
||||
"js-queue": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/js-queue/-/js-queue-2.0.0.tgz",
|
||||
"integrity": "sha1-NiITz4YPRo8BJfxslqvBdCUx+Ug=",
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/js-queue/-/js-queue-2.0.2.tgz",
|
||||
"integrity": "sha512-pbKLsbCfi7kriM3s1J4DDCo7jQkI58zPLHi0heXPzPlj0hjUsm+FesPUbE0DSbIVIK503A36aUBoCN7eMFedkA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"easy-stack": "^1.0.0"
|
||||
"easy-stack": "^1.0.1"
|
||||
}
|
||||
},
|
||||
"js-sha256": {
|
||||
@ -11919,14 +11918,14 @@
|
||||
"integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs="
|
||||
},
|
||||
"node-ipc": {
|
||||
"version": "9.1.1",
|
||||
"resolved": "https://registry.npmjs.org/node-ipc/-/node-ipc-9.1.1.tgz",
|
||||
"integrity": "sha512-FAyICv0sIRJxVp3GW5fzgaf9jwwRQxAKDJlmNFUL5hOy+W4X/I5AypyHoq0DXXbo9o/gt79gj++4cMr4jVWE/w==",
|
||||
"version": "9.1.3",
|
||||
"resolved": "https://registry.npmjs.org/node-ipc/-/node-ipc-9.1.3.tgz",
|
||||
"integrity": "sha512-8RS4RZyS/KMKKYG8mrje+cLxwATe9dBCuOiqKFSWND4oOuKytfuKCiR9yinvhoXF/nGdX/WnbywaUee+9U87zA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"event-pubsub": "4.3.0",
|
||||
"js-message": "1.0.5",
|
||||
"js-queue": "2.0.0"
|
||||
"js-message": "1.0.7",
|
||||
"js-queue": "2.0.2"
|
||||
}
|
||||
},
|
||||
"node-libs-browser": {
|
||||
@ -13830,13 +13829,13 @@
|
||||
}
|
||||
},
|
||||
"prompts": {
|
||||
"version": "2.3.2",
|
||||
"resolved": "https://registry.npmjs.org/prompts/-/prompts-2.3.2.tgz",
|
||||
"integrity": "sha512-Q06uKs2CkNYVID0VqwfAl9mipo99zkBv/n2JtWY89Yxa3ZabWSrs0e2KTudKVa3peLUvYXMefDqIleLPVUBZMA==",
|
||||
"version": "2.4.0",
|
||||
"resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.0.tgz",
|
||||
"integrity": "sha512-awZAKrk3vN6CroQukBL+R9051a4R3zCZBlJm/HBfrSZ8iTpYix3VX1vU4mveiLpiwmOJT4wokTF9m6HUk4KqWQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"kleur": "^3.0.3",
|
||||
"sisteransi": "^1.0.4"
|
||||
"sisteransi": "^1.0.5"
|
||||
}
|
||||
},
|
||||
"protoduck": {
|
||||
|
@ -65,7 +65,7 @@
|
||||
"@angular-devkit/build-angular": "^0.1000.6",
|
||||
"@angular/cli": "^10.0.6",
|
||||
"@angular/compiler-cli": "^10.0.10",
|
||||
"@rbkmoney/angular-templates": "^0.1.2",
|
||||
"@rbkmoney/angular-templates": "^0.2.2",
|
||||
"@types/del": "^4.0.0",
|
||||
"@types/glob": "^7.1.3",
|
||||
"@types/humanize-duration": "~3.18.0",
|
||||
|
@ -35,11 +35,11 @@ import { SearchClaimsModule } from './sections/search-claims/search-claims.modul
|
||||
import { SearchPartiesModule } from './sections/search-parties/search-parties.module';
|
||||
import { SettingsModule } from './settings';
|
||||
import { ThemeManager, ThemeManagerModule, ThemeName } from './theme-manager';
|
||||
import { DEFAULT_DIALOG_CONFIG, DEFAULT_SEARCH_LIMIT, DIALOG_CONFIG, SEARCH_LIMIT } from './tokens';
|
||||
|
||||
/**
|
||||
* For use in specific locations (for example, questionary PDF document)
|
||||
*/
|
||||
|
||||
moment.locale('en');
|
||||
|
||||
@NgModule({
|
||||
@ -78,6 +78,8 @@ moment.locale('en');
|
||||
{ provide: MAT_DATE_FORMATS, useValue: MAT_MOMENT_DATE_FORMATS },
|
||||
{ provide: DateAdapter, useClass: MomentDateAdapter, deps: [MAT_DATE_LOCALE] },
|
||||
{ provide: MAT_DATE_LOCALE, useValue: 'en' },
|
||||
{ provide: SEARCH_LIMIT, useValue: DEFAULT_SEARCH_LIMIT },
|
||||
{ provide: DIALOG_CONFIG, useValue: DEFAULT_DIALOG_CONFIG },
|
||||
],
|
||||
bootstrap: [AppComponent],
|
||||
})
|
||||
|
@ -9,6 +9,9 @@ import { DomainService as ThriftDomainService } from '../thrift-services/damsel/
|
||||
import { DomainObject, Reference } from '../thrift-services/damsel/gen-model/domain';
|
||||
import { Commit, Snapshot } from '../thrift-services/damsel/gen-model/domain_config';
|
||||
|
||||
/**
|
||||
* @deprecated duplicates thrift-services/damsel/domain-cache.service
|
||||
*/
|
||||
@Injectable()
|
||||
export class DomainService {
|
||||
private shapshot$: Observable<Snapshot>;
|
||||
@ -17,16 +20,25 @@ export class DomainService {
|
||||
this.updateSnapshot();
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated use DomainCacheService -> snapshot$
|
||||
*/
|
||||
get shapshot() {
|
||||
return this.shapshot$;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated use DomainCacheService -> version$
|
||||
*/
|
||||
get version$(): Observable<number> {
|
||||
return this.shapshot$.pipe(
|
||||
map(({ version }) => (version ? version.toNumber() : undefined))
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated use DomainCacheService -> getObjects or specific service from thrift-services/damsel
|
||||
*/
|
||||
getDomainObject(ref: Reference): Observable<DomainObject | null> {
|
||||
return this.shapshot$.pipe(
|
||||
map(({ domain }) => {
|
||||
@ -42,10 +54,16 @@ export class DomainService {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated use DomainCacheService -> forceReload()
|
||||
*/
|
||||
updateSnapshot() {
|
||||
return (this.shapshot$ = this.thriftDomainService.checkout(toGenReference()));
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated use DomainCacheService -> commit()
|
||||
*/
|
||||
commit(commit: Commit) {
|
||||
return this.shapshot$.pipe(
|
||||
switchMap(({ version }) =>
|
||||
|
@ -0,0 +1,25 @@
|
||||
<div fxLayout="column" fxLayoutGap="32px">
|
||||
<div class="cc-headline">Change Delegate Ruleset</div>
|
||||
|
||||
<div [formGroup]="form" fxLayout="column" fxLayoutGap="24px">
|
||||
<mat-form-field>
|
||||
<mat-label>Delegate Ruleset</mat-label>
|
||||
<mat-select formControlName="rulesetRefId" required>
|
||||
<mat-option *ngFor="let i of rulesets$ | async" [value]="i.ref.id">
|
||||
#{{ i.ref.id }} {{ i.data.name }}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field>
|
||||
<input matInput placeholder="Deligate description" formControlName="description" />
|
||||
</mat-form-field>
|
||||
</div>
|
||||
|
||||
<div fxLayout fxLayoutAlign="space-between">
|
||||
<button mat-button (click)="cancel()">CANCEL</button>
|
||||
<button mat-button color="primary" (click)="changeRuleset()" [disabled]="form.invalid">
|
||||
CHANGE RULESET
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
@ -0,0 +1,36 @@
|
||||
import { Component, DebugElement } from '@angular/core';
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { By } from '@angular/platform-browser';
|
||||
|
||||
import { ChangeDelegateRulesetDialogComponent } from './change-delegate-ruleset-dialog.component';
|
||||
|
||||
@Component({
|
||||
selector: 'cc-host',
|
||||
template: `<dsh-change-delegate-ruleset-dialog></dsh-change-delegate-ruleset-dialog>`,
|
||||
})
|
||||
class HostComponent {}
|
||||
|
||||
describe('ChangeDelegateRulesetDialogComponent', () => {
|
||||
let fixture: ComponentFixture<HostComponent>;
|
||||
let debugElement: DebugElement;
|
||||
let component: ChangeDelegateRulesetDialogComponent;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
imports: [],
|
||||
declarations: [HostComponent, ChangeDelegateRulesetDialogComponent],
|
||||
}).compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(HostComponent);
|
||||
debugElement = fixture.debugElement.query(
|
||||
By.directive(ChangeDelegateRulesetDialogComponent)
|
||||
);
|
||||
component = debugElement.componentInstance;
|
||||
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should be created', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
@ -0,0 +1,60 @@
|
||||
import { ChangeDetectionStrategy, Component, Inject, OnInit } from '@angular/core';
|
||||
import { FormBuilder } from '@angular/forms';
|
||||
import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
|
||||
import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy';
|
||||
import { map } from 'rxjs/operators';
|
||||
|
||||
import { RoutingRulesService } from '../../../thrift-services';
|
||||
|
||||
@UntilDestroy()
|
||||
@Component({
|
||||
selector: 'cc-change-delegate-ruleset-dialog',
|
||||
templateUrl: 'change-delegate-ruleset-dialog.component.html',
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class ChangeDelegateRulesetDialogComponent implements OnInit {
|
||||
form = this.fb.group({
|
||||
rulesetRefId: [],
|
||||
description: '',
|
||||
});
|
||||
|
||||
rulesets$ = this.routingRulesService.rulesets$;
|
||||
|
||||
constructor(
|
||||
private fb: FormBuilder,
|
||||
private dialogRef: MatDialogRef<ChangeDelegateRulesetDialogComponent>,
|
||||
@Inject(MAT_DIALOG_DATA) public data: { mainRulesetRefID: number; delegateIdx: number },
|
||||
private routingRulesService: RoutingRulesService
|
||||
) {}
|
||||
|
||||
ngOnInit() {
|
||||
this.routingRulesService
|
||||
.getRuleset(this.data.mainRulesetRefID)
|
||||
.pipe(
|
||||
map((r) => r?.data?.decisions?.delegates?.[this.data?.delegateIdx]),
|
||||
untilDestroyed(this)
|
||||
)
|
||||
.subscribe((delegate) => {
|
||||
this.form.patchValue({
|
||||
rulesetRefId: delegate?.ruleset?.id,
|
||||
description: delegate?.description,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
cancel() {
|
||||
this.dialogRef.close();
|
||||
}
|
||||
|
||||
changeRuleset() {
|
||||
this.routingRulesService
|
||||
.changeDelegateRuleset({
|
||||
mainRulesetRefID: this.data.mainRulesetRefID,
|
||||
delegateIdx: this.data.delegateIdx,
|
||||
newDelegateRulesetRefID: this.form.value.rulesetRefId,
|
||||
description: this.form.value.description,
|
||||
})
|
||||
.pipe(untilDestroyed(this))
|
||||
.subscribe(() => this.dialogRef.close());
|
||||
}
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { NgModule } from '@angular/core';
|
||||
import { FlexLayoutModule } from '@angular/flex-layout';
|
||||
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
import { MatInputModule } from '@angular/material/input';
|
||||
import { MatSelectModule } from '@angular/material/select';
|
||||
|
||||
import { ChangeDelegateRulesetDialogComponent } from './change-delegate-ruleset-dialog.component';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
CommonModule,
|
||||
FlexLayoutModule,
|
||||
ReactiveFormsModule,
|
||||
FormsModule,
|
||||
MatInputModule,
|
||||
MatButtonModule,
|
||||
MatSelectModule,
|
||||
],
|
||||
declarations: [ChangeDelegateRulesetDialogComponent],
|
||||
exports: [ChangeDelegateRulesetDialogComponent],
|
||||
providers: [],
|
||||
})
|
||||
export class ChangeDelegateRulesetDialogModule {}
|
@ -0,0 +1,2 @@
|
||||
export * from './change-delegate-ruleset-dialog.component';
|
||||
export * from './change-delegate-ruleset-dialog.module';
|
@ -1,5 +1,5 @@
|
||||
<div fxLayout="column" fxLayoutGap="32px">
|
||||
<div class="cc-headline">Change party delegate ruleset</div>
|
||||
<div class="cc-headline">Change main ruleset</div>
|
||||
|
||||
<cc-target-ruleset-form
|
||||
(valueChanges)="targetRuleset$.next($event)"
|
||||
|
@ -1,8 +1,8 @@
|
||||
import { ChangeDetectionStrategy, Component, Inject } from '@angular/core';
|
||||
import { MatDialogConfig, MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
|
||||
import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
|
||||
import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy';
|
||||
import { BehaviorSubject } from 'rxjs';
|
||||
import { PaymentRoutingRulesService } from 'src/app/thrift-services';
|
||||
import { RoutingRulesService } from 'src/app/thrift-services';
|
||||
|
||||
import { ErrorService } from '../../../shared/services/error';
|
||||
import { TargetRuleset } from '../target-ruleset-form';
|
||||
@ -13,45 +13,37 @@ import { TargetRuleset } from '../target-ruleset-form';
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class ChangeTargetDialogComponent {
|
||||
static defaultConfig: MatDialogConfig = {
|
||||
disableClose: true,
|
||||
width: '548px',
|
||||
maxHeight: '90vh',
|
||||
};
|
||||
|
||||
targetRuleset$ = new BehaviorSubject<TargetRuleset>(undefined);
|
||||
targetRulesetValid$ = new BehaviorSubject<boolean>(undefined);
|
||||
initValue: Partial<TargetRuleset> = {};
|
||||
|
||||
constructor(
|
||||
private dialogRef: MatDialogRef<ChangeTargetDialogComponent>,
|
||||
private paymentRoutingRulesService: PaymentRoutingRulesService,
|
||||
@Inject(MAT_DIALOG_DATA)
|
||||
public data: { mainRulesetRefID: number; rulesetID: number },
|
||||
private routingRulesService: RoutingRulesService,
|
||||
@Inject(MAT_DIALOG_DATA) public data: { mainRulesetRefID: number; delegateIdx: number },
|
||||
private errorService: ErrorService
|
||||
) {
|
||||
this.paymentRoutingRulesService
|
||||
this.routingRulesService
|
||||
.getRuleset(data?.mainRulesetRefID)
|
||||
.pipe(untilDestroyed(this))
|
||||
.subscribe((ruleset) => {
|
||||
this.initValue = {
|
||||
mainRulesetRefID: ruleset.ref.id,
|
||||
mainDelegateDescription: ruleset?.data?.decisions?.delegates?.find(
|
||||
(d) => d?.ruleset?.id === data?.rulesetID
|
||||
)?.description,
|
||||
mainDelegateDescription:
|
||||
ruleset?.data?.decisions?.delegates?.[data?.delegateIdx]?.description,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
changeTarget() {
|
||||
const { mainRulesetRefID, mainDelegateDescription } = this.targetRuleset$.value;
|
||||
const { mainRulesetRefID: previousMainRulesetRefID, rulesetID } = this.data;
|
||||
this.paymentRoutingRulesService
|
||||
.changeDelegateRuleset({
|
||||
const { mainRulesetRefID: previousMainRulesetRefID, delegateIdx } = this.data;
|
||||
this.routingRulesService
|
||||
.changeMainRuleset({
|
||||
previousMainRulesetRefID,
|
||||
mainRulesetRefID,
|
||||
mainDelegateDescription,
|
||||
rulesetID,
|
||||
delegateIdx,
|
||||
})
|
||||
.pipe(untilDestroyed(this))
|
||||
.subscribe(() => this.dialogRef.close(), this.errorService.error);
|
||||
|
@ -1,9 +1,9 @@
|
||||
import { ChangeDetectionStrategy, Component, Inject } from '@angular/core';
|
||||
import { FormBuilder } from '@angular/forms';
|
||||
import { MatDialogConfig, MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
|
||||
import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
|
||||
import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy';
|
||||
import { BehaviorSubject } from 'rxjs';
|
||||
import { PaymentRoutingRulesService } from 'src/app/thrift-services';
|
||||
import { RoutingRulesService } from 'src/app/thrift-services';
|
||||
|
||||
import { ErrorService } from '../../../../shared/services/error';
|
||||
import { TargetRuleset } from '../../target-ruleset-form';
|
||||
@ -14,12 +14,6 @@ import { TargetRuleset } from '../../target-ruleset-form';
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class AttachNewRulesetDialogComponent {
|
||||
static defaultConfig: MatDialogConfig = {
|
||||
disableClose: true,
|
||||
width: '548px',
|
||||
maxHeight: '90vh',
|
||||
};
|
||||
|
||||
form = this.fb.group({
|
||||
ruleset: this.fb.group({
|
||||
name: 'submain ruleset[by shop id]',
|
||||
@ -33,7 +27,7 @@ export class AttachNewRulesetDialogComponent {
|
||||
constructor(
|
||||
private fb: FormBuilder,
|
||||
private dialogRef: MatDialogRef<AttachNewRulesetDialogComponent>,
|
||||
private paymentRoutingRulesService: PaymentRoutingRulesService,
|
||||
private paymentRoutingRulesService: RoutingRulesService,
|
||||
@Inject(MAT_DIALOG_DATA) public data: { partyID: string },
|
||||
private errorService: ErrorService
|
||||
) {}
|
||||
|
@ -2,7 +2,7 @@
|
||||
<mat-progress-bar mode="indeterminate"></mat-progress-bar>
|
||||
</ng-container>
|
||||
<ng-template #loaded>
|
||||
<div fxLayout="column" [fxLayoutGap]="(dataSource$ | async)?.data?.length ? '24px' : '64px'">
|
||||
<div fxLayout="column" [fxLayoutGap]="(data$ | async)?.length ? '24px' : '64px'">
|
||||
<div fxLayout fxLayoutGap="8px" fxLayoutAlign="space-between center">
|
||||
<div class="cc-headline">Party delegate rulesets</div>
|
||||
<button mat-button color="primary" (click)="attachNewRuleset()">
|
||||
@ -10,80 +10,10 @@
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<mat-card *ngIf="(dataSource$ | async)?.data?.length; else emptyPartyDelegateRulesets">
|
||||
<mat-card-content fxLayout="column">
|
||||
<table mat-table [dataSource]="dataSource$ | async" fxFlex>
|
||||
<ng-container matColumnDef="paymentInstitution">
|
||||
<th mat-header-cell *matHeaderCellDef>Payment institution</th>
|
||||
<td mat-cell *matCellDef="let element">
|
||||
{{ element?.paymentInstitution?.data?.name }}
|
||||
</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="mainRuleset">
|
||||
<th mat-header-cell *matHeaderCellDef>Main Ruleset</th>
|
||||
<td mat-cell *matCellDef="let element">
|
||||
{{ element?.mainRuleset?.data?.name }}
|
||||
</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="partyDelegate">
|
||||
<th mat-header-cell *matHeaderCellDef>Party delegate</th>
|
||||
<td mat-cell *matCellDef="let element">
|
||||
{{ element?.partyDelegate?.description }}
|
||||
</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="actions">
|
||||
<th mat-header-cell *matHeaderCellDef width="1px"></th>
|
||||
<td mat-cell *matCellDef="let element">
|
||||
<button mat-icon-button [matMenuTriggerFor]="menu">
|
||||
<mat-icon>more_vert</mat-icon>
|
||||
</button>
|
||||
<mat-menu #menu="matMenu">
|
||||
<button
|
||||
mat-menu-item
|
||||
(click)="
|
||||
navigateToPartyRuleset(element?.partyDelegate?.ruleset?.id)
|
||||
"
|
||||
>
|
||||
Details
|
||||
</button>
|
||||
<button
|
||||
mat-menu-item
|
||||
(click)="
|
||||
changeTarget(
|
||||
element?.mainRuleset?.ref?.id,
|
||||
element?.partyDelegate?.ruleset?.id
|
||||
)
|
||||
"
|
||||
>
|
||||
Change target
|
||||
</button>
|
||||
<button
|
||||
mat-menu-item
|
||||
(click)="
|
||||
deleteRuleset(
|
||||
element?.mainRuleset?.ref?.id,
|
||||
element?.partyDelegate?.ruleset?.id
|
||||
)
|
||||
"
|
||||
>
|
||||
Delete
|
||||
</button>
|
||||
</mat-menu>
|
||||
</td>
|
||||
</ng-container>
|
||||
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: displayedColumns"></tr>
|
||||
</table>
|
||||
|
||||
<mat-paginator
|
||||
[pageSizeOptions]="[10, 20, 50, 100, 250, 500]"
|
||||
showFirstLastButtons
|
||||
></mat-paginator>
|
||||
</mat-card-content>
|
||||
</mat-card>
|
||||
|
||||
<ng-template #emptyPartyDelegateRulesets>
|
||||
<div class="cc-display-1" fxFlexAlign="center">Party delegate rulesets not found</div>
|
||||
</ng-template>
|
||||
<cc-routing-rules-list
|
||||
[data]="data$ | async"
|
||||
[displayedColumns]="displayedColumns"
|
||||
(toDetails)="navigateToPartyRuleset($event.parentRefId, $event.delegateIdx)"
|
||||
></cc-routing-rules-list>
|
||||
</div>
|
||||
</ng-template>
|
||||
|
@ -1,19 +1,15 @@
|
||||
import { ChangeDetectionStrategy, Component, ViewChild } from '@angular/core';
|
||||
import { ChangeDetectionStrategy, Component, Inject } from '@angular/core';
|
||||
import { MatDialog } from '@angular/material/dialog';
|
||||
import { MatPaginator } from '@angular/material/paginator';
|
||||
import { MatTableDataSource } from '@angular/material/table';
|
||||
import { Router } from '@angular/router';
|
||||
import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy';
|
||||
import { combineLatest, ReplaySubject } from 'rxjs';
|
||||
import { filter, first, map, shareReplay, startWith, switchMap, take } from 'rxjs/operators';
|
||||
|
||||
import { ConfirmActionDialogComponent } from '@cc/components/confirm-action-dialog';
|
||||
import { combineLatest } from 'rxjs';
|
||||
import { first, map, switchMap, take } from 'rxjs/operators';
|
||||
|
||||
import { handleError } from '../../../../utils/operators/handle-error';
|
||||
import { ErrorService } from '../../../shared/services/error';
|
||||
import { PaymentRoutingRulesService } from '../../../thrift-services';
|
||||
import { RoutingRulesService } from '../../../thrift-services';
|
||||
import { DomainCacheService } from '../../../thrift-services/damsel/domain-cache.service';
|
||||
import { ChangeTargetDialogComponent } from '../change-target-dialog';
|
||||
import { DialogConfig, DIALOG_CONFIG } from '../../../tokens';
|
||||
import { AttachNewRulesetDialogComponent } from './attach-new-ruleset-dialog';
|
||||
import { PartyDelegateRulesetsService } from './party-delegate-rulesets.service';
|
||||
|
||||
@ -25,32 +21,43 @@ import { PartyDelegateRulesetsService } from './party-delegate-rulesets.service'
|
||||
providers: [PartyDelegateRulesetsService],
|
||||
})
|
||||
export class PartyDelegateRulesetsComponent {
|
||||
displayedColumns = ['paymentInstitution', 'mainRuleset', 'partyDelegate', 'actions'];
|
||||
displayedColumns = [
|
||||
{ key: 'paymentInstitution', name: 'Payment institution' },
|
||||
{ key: 'mainRuleset', name: 'Main ruleset' },
|
||||
{ key: 'partyDelegate', name: 'Party delegate' },
|
||||
];
|
||||
isLoading$ = this.domainService.isLoading$;
|
||||
|
||||
@ViewChild(MatPaginator) set paginator(paginator: MatPaginator) {
|
||||
this.paginator$.next(paginator);
|
||||
}
|
||||
paginator$ = new ReplaySubject<MatPaginator>(1);
|
||||
dataSource$ = combineLatest([
|
||||
this.partyDelegateRulesetsService.partyDelegateRulesets$,
|
||||
this.paginator$.pipe(startWith<any, null>(null)),
|
||||
]).pipe(
|
||||
map(([v, paginator]) => {
|
||||
const data = new MatTableDataSource(v);
|
||||
data.paginator = paginator;
|
||||
return data;
|
||||
}),
|
||||
shareReplay(1)
|
||||
data$ = this.partyDelegateRulesetsService.getDelegatesWithPaymentInstitution().pipe(
|
||||
map((rules) =>
|
||||
rules.map(({ mainRoutingRule, partyDelegate, paymentInstitution }) => ({
|
||||
parentRefId: mainRoutingRule?.ref?.id,
|
||||
delegateIdx: mainRoutingRule?.data?.decisions?.delegates?.findIndex(
|
||||
(d) => d === partyDelegate
|
||||
),
|
||||
paymentInstitution: {
|
||||
text: paymentInstitution?.data?.name,
|
||||
caption: paymentInstitution?.ref?.id,
|
||||
},
|
||||
mainRuleset: {
|
||||
text: mainRoutingRule?.data?.name,
|
||||
caption: mainRoutingRule?.ref?.id,
|
||||
},
|
||||
partyDelegate: {
|
||||
text: partyDelegate?.description,
|
||||
caption: partyDelegate?.ruleset?.id,
|
||||
},
|
||||
}))
|
||||
)
|
||||
);
|
||||
|
||||
constructor(
|
||||
private partyDelegateRulesetsService: PartyDelegateRulesetsService,
|
||||
private paymentRoutingRulesService: PaymentRoutingRulesService,
|
||||
private paymentRoutingRulesService: RoutingRulesService,
|
||||
private router: Router,
|
||||
private dialog: MatDialog,
|
||||
private domainService: DomainCacheService,
|
||||
private errorService: ErrorService
|
||||
private errorService: ErrorService,
|
||||
@Inject(DIALOG_CONFIG) private dialogConfig: DialogConfig
|
||||
) {}
|
||||
|
||||
attachNewRuleset() {
|
||||
@ -60,7 +67,7 @@ export class PartyDelegateRulesetsComponent {
|
||||
switchMap((partyID) =>
|
||||
this.dialog
|
||||
.open(AttachNewRulesetDialogComponent, {
|
||||
...AttachNewRulesetDialogComponent.defaultConfig,
|
||||
...this.dialogConfig.medium,
|
||||
data: { partyID },
|
||||
})
|
||||
.afterClosed()
|
||||
@ -71,40 +78,19 @@ export class PartyDelegateRulesetsComponent {
|
||||
.subscribe();
|
||||
}
|
||||
|
||||
navigateToPartyRuleset(id: string) {
|
||||
this.partyDelegateRulesetsService.partyID$
|
||||
navigateToPartyRuleset(parentRefId: number, delegateIdx: number) {
|
||||
combineLatest([
|
||||
this.partyDelegateRulesetsService.partyID$,
|
||||
this.paymentRoutingRulesService.getRuleset(parentRefId),
|
||||
])
|
||||
.pipe(first(), untilDestroyed(this))
|
||||
.subscribe((partyID) =>
|
||||
this.router.navigate(['party', partyID, 'payment-routing-rules', id])
|
||||
.subscribe(([partyID, parent]) =>
|
||||
this.router.navigate([
|
||||
'party',
|
||||
partyID,
|
||||
'payment-routing-rules',
|
||||
parent.data.decisions.delegates[delegateIdx].ruleset.id,
|
||||
])
|
||||
);
|
||||
}
|
||||
|
||||
changeTarget(mainRulesetRefID: string, rulesetID: string) {
|
||||
this.dialog
|
||||
.open(ChangeTargetDialogComponent, {
|
||||
...ChangeTargetDialogComponent.defaultConfig,
|
||||
data: { mainRulesetRefID, rulesetID },
|
||||
})
|
||||
.afterClosed()
|
||||
.pipe(handleError(this.errorService.error), untilDestroyed(this))
|
||||
.subscribe();
|
||||
}
|
||||
|
||||
deleteRuleset(mainRulesetRefID: number, rulesetRefID: number) {
|
||||
this.dialog
|
||||
.open(ConfirmActionDialogComponent)
|
||||
.afterClosed()
|
||||
.pipe(
|
||||
filter((r) => r === 'confirm'),
|
||||
switchMap(() =>
|
||||
this.paymentRoutingRulesService.deleteDelegate({
|
||||
mainRulesetRefID,
|
||||
rulesetRefID,
|
||||
})
|
||||
),
|
||||
handleError(this.errorService.error),
|
||||
untilDestroyed(this)
|
||||
)
|
||||
.subscribe();
|
||||
}
|
||||
}
|
||||
|
@ -13,7 +13,6 @@ import { MatPaginatorModule } from '@angular/material/paginator';
|
||||
import { MatProgressBarModule } from '@angular/material/progress-bar';
|
||||
import { MatRadioModule } from '@angular/material/radio';
|
||||
import { MatSelectModule } from '@angular/material/select';
|
||||
import { MatTableModule } from '@angular/material/table';
|
||||
import { RouterModule } from '@angular/router';
|
||||
|
||||
import { DetailsItemModule } from '@cc/components/details-item';
|
||||
@ -21,6 +20,7 @@ import { DetailsItemModule } from '@cc/components/details-item';
|
||||
import { ErrorModule } from '../../../shared/services/error';
|
||||
import { ChangeTargetDialogModule } from '../change-target-dialog';
|
||||
import { PaymentRoutingRulesetHeaderModule } from '../payment-routing-ruleset-header';
|
||||
import { RoutingRulesListModule } from '../routing-rules-list';
|
||||
import { TargetRulesetFormModule } from '../target-ruleset-form';
|
||||
import { AttachNewRulesetDialogComponent } from './attach-new-ruleset-dialog';
|
||||
import { PartyDelegateRulesetsRoutingModule } from './party-delegate-rulesets-routing.module';
|
||||
@ -37,7 +37,6 @@ const EXPORTED_DECLARATIONS = [PartyDelegateRulesetsComponent, AttachNewRulesetD
|
||||
CommonModule,
|
||||
RouterModule,
|
||||
MatCardModule,
|
||||
MatTableModule,
|
||||
MatIconModule,
|
||||
MatPaginatorModule,
|
||||
MatMenuModule,
|
||||
@ -52,6 +51,7 @@ const EXPORTED_DECLARATIONS = [PartyDelegateRulesetsComponent, AttachNewRulesetD
|
||||
ErrorModule,
|
||||
ChangeTargetDialogModule,
|
||||
TargetRulesetFormModule,
|
||||
RoutingRulesListModule,
|
||||
],
|
||||
declarations: EXPORTED_DECLARATIONS,
|
||||
exports: EXPORTED_DECLARATIONS,
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { combineLatest } from 'rxjs';
|
||||
import { map, pluck, shareReplay, startWith } from 'rxjs/operators';
|
||||
import { map, pluck, startWith, switchMap } from 'rxjs/operators';
|
||||
import { DomainCacheService } from 'src/app/thrift-services/damsel/domain-cache.service';
|
||||
import {
|
||||
PaymentInstitutionObject,
|
||||
@ -9,68 +9,67 @@ import {
|
||||
RoutingRulesObject,
|
||||
} from 'src/app/thrift-services/damsel/gen-model/domain';
|
||||
|
||||
import { PaymentRoutingRulesService } from '../../../thrift-services';
|
||||
import { RoutingRulesService } from '../../../thrift-services';
|
||||
|
||||
@Injectable()
|
||||
export class PartyDelegateRulesetsService {
|
||||
partyID$ = this.route.params.pipe(startWith(this.route.snapshot.params), pluck('partyID'));
|
||||
|
||||
partyDelegateRulesets$ = combineLatest([
|
||||
this.domainService.getObjects('payment_institution'),
|
||||
this.paymentRoutingRulesService.rulesets$,
|
||||
this.partyID$,
|
||||
]).pipe(
|
||||
map(([institutions, rules, partyID]) => {
|
||||
const rulesetsWithInstitution = institutions
|
||||
.map(
|
||||
(i) =>
|
||||
[
|
||||
rules.find(
|
||||
(r) => r?.ref?.id === i?.data?.payment_routing_rules?.policies?.id
|
||||
),
|
||||
i,
|
||||
] as const
|
||||
)
|
||||
.filter(([r]) => r);
|
||||
const partyDelegateRulesets = rulesetsWithInstitution
|
||||
.map(
|
||||
([r, i]) =>
|
||||
[
|
||||
r,
|
||||
i,
|
||||
r?.data?.decisions?.delegates
|
||||
?.map((d) =>
|
||||
d?.allowed?.condition?.party?.id === partyID ? d : undefined
|
||||
)
|
||||
?.filter((d) => d),
|
||||
] as const
|
||||
)
|
||||
.filter(([, , d]) => d?.length)
|
||||
.reduce(
|
||||
(acc, [r, i, d]) => {
|
||||
acc.push(
|
||||
...d.map((partyDelegate) => ({
|
||||
partyDelegate,
|
||||
paymentInstitution: i,
|
||||
mainRuleset: r,
|
||||
}))
|
||||
);
|
||||
return acc;
|
||||
},
|
||||
[] as {
|
||||
partyDelegate: RoutingDelegate;
|
||||
paymentInstitution: PaymentInstitutionObject;
|
||||
mainRuleset: RoutingRulesObject;
|
||||
}[]
|
||||
);
|
||||
return partyDelegateRulesets;
|
||||
}),
|
||||
shareReplay(1)
|
||||
);
|
||||
|
||||
constructor(
|
||||
private domainService: DomainCacheService,
|
||||
private route: ActivatedRoute,
|
||||
private paymentRoutingRulesService: PaymentRoutingRulesService
|
||||
private paymentRoutingRulesService: RoutingRulesService
|
||||
) {}
|
||||
|
||||
getDelegatesWithPaymentInstitution() {
|
||||
return combineLatest([this.getPaymentInstitutionsWithRoutingRule(), this.partyID$]).pipe(
|
||||
map(([paymentInstitutionsWithRoutingRule, partyID]) =>
|
||||
paymentInstitutionsWithRoutingRule
|
||||
.map(({ routingRule: mainRoutingRule, paymentInstitution }) => ({
|
||||
mainRoutingRule,
|
||||
paymentInstitution,
|
||||
delegates: mainRoutingRule?.data?.decisions?.delegates
|
||||
?.map((d) =>
|
||||
d?.allowed?.condition?.party?.id === partyID ? d : undefined
|
||||
)
|
||||
?.filter((d) => d),
|
||||
}))
|
||||
.filter(({ delegates }) => delegates?.length)
|
||||
.reduce<
|
||||
{
|
||||
partyDelegate: RoutingDelegate;
|
||||
paymentInstitution: PaymentInstitutionObject;
|
||||
mainRoutingRule: RoutingRulesObject;
|
||||
}[]
|
||||
>(
|
||||
(acc, { delegates, ...rest }) => [
|
||||
...acc,
|
||||
...delegates.map((partyDelegate) => ({ ...rest, partyDelegate })),
|
||||
],
|
||||
[]
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
private getPaymentInstitutionsWithRoutingRule() {
|
||||
return this.domainService.getObjects('payment_institution').pipe(
|
||||
switchMap((paymentInstitutions) =>
|
||||
combineLatest(
|
||||
paymentInstitutions.map((paymentInstitution) =>
|
||||
this.paymentRoutingRulesService
|
||||
.getRuleset(
|
||||
paymentInstitution?.data?.payment_routing_rules?.policies?.id
|
||||
)
|
||||
.pipe(
|
||||
map((routingRule) => ({
|
||||
paymentInstitution,
|
||||
routingRule,
|
||||
}))
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
|
||||
import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy';
|
||||
|
||||
import { ErrorService } from '../../../../shared/services/error';
|
||||
import { PaymentRoutingRulesService } from '../../../../thrift-services';
|
||||
import { RoutingRulesService } from '../../../../thrift-services';
|
||||
import { Shop } from '../../../../thrift-services/damsel/gen-model/domain';
|
||||
|
||||
@UntilDestroy()
|
||||
@ -21,7 +21,7 @@ export class AddPartyPaymentRoutingRuleDialogComponent {
|
||||
constructor(
|
||||
private fb: FormBuilder,
|
||||
private dialogRef: MatDialogRef<AddPartyPaymentRoutingRuleDialogComponent>,
|
||||
private paymentRoutingRulesService: PaymentRoutingRulesService,
|
||||
private paymentRoutingRulesService: RoutingRulesService,
|
||||
@Inject(MAT_DIALOG_DATA)
|
||||
public data: { refID: number; partyID: string; shops: Shop[] },
|
||||
private errorService: ErrorService
|
||||
|
@ -4,7 +4,7 @@ import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
|
||||
import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy';
|
||||
|
||||
import { ErrorService } from '../../../../shared/services/error';
|
||||
import { PaymentRoutingRulesService } from '../../../../thrift-services';
|
||||
import { RoutingRulesService } from '../../../../thrift-services';
|
||||
|
||||
@UntilDestroy()
|
||||
@Component({
|
||||
@ -21,7 +21,7 @@ export class InitializePaymentRoutingRulesDialogComponent {
|
||||
constructor(
|
||||
private fb: FormBuilder,
|
||||
private dialogRef: MatDialogRef<InitializePaymentRoutingRulesDialogComponent>,
|
||||
private paymentRoutingRulesService: PaymentRoutingRulesService,
|
||||
private paymentRoutingRulesService: RoutingRulesService,
|
||||
@Inject(MAT_DIALOG_DATA) public data: { partyID: string; refID: number },
|
||||
private errorService: ErrorService
|
||||
) {}
|
||||
|
@ -15,57 +15,11 @@
|
||||
Party payment routing rules
|
||||
</cc-payment-routing-ruleset-header>
|
||||
|
||||
<mat-card *ngIf="(dataSource$ | async)?.data?.length; else emptyPartyRuleset">
|
||||
<mat-card-content fxLayout="column">
|
||||
<table mat-table [dataSource]="dataSource$ | async" fxFlex>
|
||||
<ng-container matColumnDef="shop">
|
||||
<th mat-header-cell *matHeaderCellDef width="50%">Shop</th>
|
||||
<td mat-cell *matCellDef="let element">
|
||||
<div fxLayout="column">
|
||||
<div class="cc-body-1">{{ element.shop.details?.name }}</div>
|
||||
<div class="cc-caption">{{ element.shop.id }}</div>
|
||||
</div>
|
||||
</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="id">
|
||||
<th mat-header-cell *matHeaderCellDef width="50%">Ruleset Ref ID</th>
|
||||
<td mat-cell *matCellDef="let element">{{ element.id }}</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="actions">
|
||||
<th mat-header-cell *matHeaderCellDef></th>
|
||||
<td mat-cell *matCellDef="let element">
|
||||
<button mat-icon-button [matMenuTriggerFor]="menu">
|
||||
<mat-icon>more_vert</mat-icon>
|
||||
</button>
|
||||
<mat-menu #menu="matMenu">
|
||||
<button mat-menu-item (click)="navigateToShopRuleset(element.id)">
|
||||
Details
|
||||
</button>
|
||||
<button mat-menu-item (click)="changeTarget(element.id)">
|
||||
Change target
|
||||
</button>
|
||||
<button mat-menu-item (click)="deleteRuleset(element.id)">
|
||||
Delete
|
||||
</button>
|
||||
</mat-menu>
|
||||
</td>
|
||||
</ng-container>
|
||||
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: displayedColumns"></tr>
|
||||
</table>
|
||||
|
||||
<mat-paginator
|
||||
[pageSizeOptions]="[10, 20, 50, 100, 250, 500]"
|
||||
showFirstLastButtons
|
||||
></mat-paginator>
|
||||
</mat-card-content>
|
||||
</mat-card>
|
||||
|
||||
<ng-template #emptyPartyRuleset>
|
||||
<div class="cc-display-1" fxFlexAlign="center">
|
||||
Party payment routing rules is empty
|
||||
</div>
|
||||
</ng-template>
|
||||
<cc-routing-rules-list
|
||||
[data]="data$ | async"
|
||||
[displayedColumns]="displayedColumns"
|
||||
(toDetails)="navigateToShopRuleset($event.parentRefId, $event.delegateIdx)"
|
||||
></cc-routing-rules-list>
|
||||
</div>
|
||||
|
||||
<ng-template #emptyPartyDelegate>
|
||||
@ -75,7 +29,7 @@
|
||||
fxLayoutAlign=" center"
|
||||
fxLayoutGap="24px"
|
||||
>
|
||||
<div class="cc-display-1">Payment rules is not found</div>
|
||||
<div class="cc-display-1">Payment rules not found</div>
|
||||
<button mat-raised-button color="primary" (click)="initialize()" class="init">
|
||||
INITIALIZE
|
||||
</button>
|
||||
|
@ -1,25 +1,16 @@
|
||||
import { Component, ViewChild } from '@angular/core';
|
||||
import { Component, Inject } from '@angular/core';
|
||||
import { MatDialog } from '@angular/material/dialog';
|
||||
import { MatPaginator } from '@angular/material/paginator';
|
||||
import { MatTableDataSource } from '@angular/material/table';
|
||||
import { Router } from '@angular/router';
|
||||
import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy';
|
||||
import { combineLatest, ReplaySubject } from 'rxjs';
|
||||
import { filter, map, shareReplay, switchMap, take, withLatestFrom } from 'rxjs/operators';
|
||||
import { combineLatest } from 'rxjs';
|
||||
import { filter, map, shareReplay, switchMap, take } from 'rxjs/operators';
|
||||
|
||||
import { ConfirmActionDialogComponent } from '@cc/components/confirm-action-dialog';
|
||||
|
||||
import { handleError } from '../../../../utils/operators/handle-error';
|
||||
import { ErrorService } from '../../../shared/services/error';
|
||||
import { PaymentRoutingRulesService } from '../../../thrift-services';
|
||||
import { DomainCacheService } from '../../../thrift-services/damsel/domain-cache.service';
|
||||
import { ChangeTargetDialogComponent } from '../change-target-dialog';
|
||||
import { DialogConfig, DIALOG_CONFIG } from '../../../tokens';
|
||||
import { AddPartyPaymentRoutingRuleDialogComponent } from './add-party-payment-routing-rule-dialog';
|
||||
import { InitializePaymentRoutingRulesDialogComponent } from './initialize-payment-routing-rules-dialog';
|
||||
import { PartyPaymentRoutingRulesetService } from './party-payment-routing-ruleset.service';
|
||||
|
||||
const DIALOG_WIDTH = '548px';
|
||||
|
||||
@UntilDestroy()
|
||||
@Component({
|
||||
selector: 'cc-party-payment-routing-ruleset',
|
||||
@ -30,44 +21,44 @@ const DIALOG_WIDTH = '548px';
|
||||
export class PaymentRoutingRulesComponent {
|
||||
partyRuleset$ = this.partyPaymentRoutingRulesetService.partyRuleset$;
|
||||
partyID$ = this.partyPaymentRoutingRulesetService.partyID$;
|
||||
displayedColumns = ['shop', 'id', 'actions'];
|
||||
isLoading$ = this.domainService.isLoading$;
|
||||
|
||||
@ViewChild(MatPaginator) set paginator(paginator: MatPaginator) {
|
||||
this.paginator$.next(paginator);
|
||||
}
|
||||
paginator$ = new ReplaySubject<MatPaginator>(1);
|
||||
dataSource$ = combineLatest([
|
||||
this.partyRuleset$,
|
||||
this.partyPaymentRoutingRulesetService.shops$,
|
||||
this.paginator$,
|
||||
]).pipe(
|
||||
displayedColumns = [
|
||||
{ key: 'shop', name: 'Shop' },
|
||||
{ key: 'id', name: 'Delegate (Ruleset Ref ID)' },
|
||||
];
|
||||
data$ = combineLatest([this.partyRuleset$, this.partyPaymentRoutingRulesetService.shops$]).pipe(
|
||||
filter(([r]) => !!r),
|
||||
map(([ruleset, shops, paginator]) => {
|
||||
const data = new MatTableDataSource(
|
||||
ruleset.data.decisions.delegates
|
||||
.filter((d) => d?.allowed?.condition?.party?.definition?.shop_is)
|
||||
.map((d) => {
|
||||
const shopId = d.allowed.condition.party.definition.shop_is;
|
||||
return {
|
||||
id: d.ruleset.id,
|
||||
shop: shops.find((s) => s.id === shopId) || { id: shopId },
|
||||
};
|
||||
})
|
||||
);
|
||||
data.paginator = paginator;
|
||||
return data;
|
||||
}),
|
||||
map(([ruleset, shops]) =>
|
||||
ruleset.data.decisions.delegates
|
||||
.filter((d) => d?.allowed?.condition?.party?.definition?.shop_is)
|
||||
.map((delegate) => {
|
||||
const shopId = delegate.allowed.condition.party.definition.shop_is;
|
||||
return {
|
||||
parentRefId: ruleset.ref.id,
|
||||
delegateIdx: ruleset.data.decisions.delegates.findIndex(
|
||||
(d) => d === delegate
|
||||
),
|
||||
id: {
|
||||
text: delegate?.description,
|
||||
caption: delegate?.ruleset?.id,
|
||||
},
|
||||
shop: {
|
||||
text: shops?.find((s) => s?.id === shopId)?.details?.name,
|
||||
caption: shopId,
|
||||
},
|
||||
};
|
||||
})
|
||||
),
|
||||
shareReplay(1)
|
||||
);
|
||||
|
||||
constructor(
|
||||
private dialog: MatDialog,
|
||||
private partyPaymentRoutingRulesetService: PartyPaymentRoutingRulesetService,
|
||||
private paymentRoutingRulesService: PaymentRoutingRulesService,
|
||||
private router: Router,
|
||||
private domainService: DomainCacheService,
|
||||
private errorService: ErrorService
|
||||
@Inject(DIALOG_CONFIG) private dialogConfig: DialogConfig
|
||||
) {}
|
||||
|
||||
initialize() {
|
||||
@ -80,9 +71,7 @@ export class PaymentRoutingRulesComponent {
|
||||
switchMap(([partyID, refID]) =>
|
||||
this.dialog
|
||||
.open(InitializePaymentRoutingRulesDialogComponent, {
|
||||
disableClose: true,
|
||||
width: DIALOG_WIDTH,
|
||||
maxHeight: '90vh',
|
||||
...this.dialogConfig.medium,
|
||||
data: { partyID, refID },
|
||||
})
|
||||
.afterClosed()
|
||||
@ -103,9 +92,7 @@ export class PaymentRoutingRulesComponent {
|
||||
switchMap(([refID, shops, partyID]) =>
|
||||
this.dialog
|
||||
.open(AddPartyPaymentRoutingRuleDialogComponent, {
|
||||
disableClose: true,
|
||||
width: DIALOG_WIDTH,
|
||||
maxHeight: '90vh',
|
||||
...this.dialogConfig.medium,
|
||||
data: { refID, shops, partyID },
|
||||
})
|
||||
.afterClosed()
|
||||
@ -115,58 +102,21 @@ export class PaymentRoutingRulesComponent {
|
||||
.subscribe();
|
||||
}
|
||||
|
||||
deleteRuleset(rulesetRefID: number) {
|
||||
this.dialog
|
||||
.open(ConfirmActionDialogComponent)
|
||||
.afterClosed()
|
||||
.pipe(
|
||||
filter((r) => r === 'confirm'),
|
||||
withLatestFrom(this.partyRuleset$),
|
||||
switchMap(([, mainRuleset]) =>
|
||||
this.paymentRoutingRulesService.deleteDelegate({
|
||||
mainRulesetRefID: mainRuleset.ref.id,
|
||||
rulesetRefID,
|
||||
})
|
||||
),
|
||||
handleError(this.errorService.error),
|
||||
untilDestroyed(this)
|
||||
)
|
||||
.subscribe();
|
||||
}
|
||||
|
||||
navigateToShopRuleset(refID: string) {
|
||||
navigateToShopRuleset(parentRefId: number, delegateIdx: number) {
|
||||
combineLatest([
|
||||
this.partyPaymentRoutingRulesetService.partyID$,
|
||||
this.partyPaymentRoutingRulesetService.refID$,
|
||||
this.partyPaymentRoutingRulesetService.partyRuleset$,
|
||||
])
|
||||
.pipe(take(1), untilDestroyed(this))
|
||||
.subscribe(([partyID, partyRefID]) =>
|
||||
.subscribe(([partyID, ruleset]) =>
|
||||
this.router.navigate([
|
||||
'party',
|
||||
partyID,
|
||||
'payment-routing-rules',
|
||||
partyRefID,
|
||||
parentRefId,
|
||||
'shop-ruleset',
|
||||
refID,
|
||||
ruleset?.data?.decisions?.delegates?.[delegateIdx]?.ruleset?.id,
|
||||
])
|
||||
);
|
||||
}
|
||||
|
||||
changeTarget(rulesetID: string) {
|
||||
this.partyRuleset$
|
||||
.pipe(
|
||||
take(1),
|
||||
switchMap((mainRuleset) =>
|
||||
this.dialog
|
||||
.open(ChangeTargetDialogComponent, {
|
||||
...ChangeTargetDialogComponent.defaultConfig,
|
||||
data: { mainRulesetRefID: mainRuleset.ref.id, rulesetID },
|
||||
})
|
||||
.afterClosed()
|
||||
),
|
||||
handleError(this.errorService.error),
|
||||
untilDestroyed(this)
|
||||
)
|
||||
.subscribe();
|
||||
}
|
||||
}
|
||||
|
@ -22,6 +22,7 @@ import { ErrorModule } from '../../../shared/services/error';
|
||||
import { DamselModule } from '../../../thrift-services';
|
||||
import { ChangeTargetDialogModule } from '../change-target-dialog';
|
||||
import { PaymentRoutingRulesetHeaderModule } from '../payment-routing-ruleset-header';
|
||||
import { RoutingRulesListModule } from '../routing-rules-list';
|
||||
import { AddPartyPaymentRoutingRuleDialogModule } from './add-party-payment-routing-rule-dialog';
|
||||
import { InitializePaymentRoutingRulesDialogModule } from './initialize-payment-routing-rules-dialog';
|
||||
import { PartyPaymentRoutingRulesetRoutingModule } from './party-payment-routing-ruleset-routing.module';
|
||||
@ -54,6 +55,7 @@ import { PaymentRoutingRulesComponent } from './party-payment-routing-ruleset.co
|
||||
MatProgressBarModule,
|
||||
ErrorModule,
|
||||
ChangeTargetDialogModule,
|
||||
RoutingRulesListModule,
|
||||
],
|
||||
declarations: [PaymentRoutingRulesComponent],
|
||||
})
|
||||
|
@ -0,0 +1,2 @@
|
||||
export * from './routing-rules-list.component';
|
||||
export * from './routing-rules-list.module';
|
@ -0,0 +1,72 @@
|
||||
<mat-card *ngIf="(dataSource$ | async)?.data?.length; else empty">
|
||||
<mat-card-content fxLayout="column">
|
||||
<table mat-table [dataSource]="dataSource$ | async">
|
||||
<ng-container [matColumnDef]="column.key" *ngFor="let column of displayedColumns">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ column.name }}</th>
|
||||
<td mat-cell *matCellDef="let element">
|
||||
<div
|
||||
fxLayout="column"
|
||||
*ngIf="
|
||||
element[column.key]?.text || element[column.key]?.caption;
|
||||
else onlyBody
|
||||
"
|
||||
>
|
||||
<div class="cc-body-1">{{ element[column.key]?.text || ' ' }}</div>
|
||||
<div class="cc-caption">
|
||||
{{ element[column.key]?.caption || ' ' }}
|
||||
</div>
|
||||
</div>
|
||||
<ng-template #onlyBody>
|
||||
{{ element[column.key] }}
|
||||
</ng-template>
|
||||
</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="actions">
|
||||
<th mat-header-cell *matHeaderCellDef width="1px"></th>
|
||||
<td mat-cell *matCellDef="let element">
|
||||
<button mat-icon-button [matMenuTriggerFor]="menu">
|
||||
<mat-icon>more_vert</mat-icon>
|
||||
</button>
|
||||
<mat-menu #menu="matMenu">
|
||||
<button
|
||||
mat-menu-item
|
||||
(click)="
|
||||
toDetails.emit({
|
||||
parentRefId: element?.parentRefId,
|
||||
delegateIdx: element?.delegateIdx
|
||||
})
|
||||
"
|
||||
>
|
||||
Details
|
||||
</button>
|
||||
<button mat-menu-item (click)="changeDelegateRuleset(element)">
|
||||
Change delegate ruleset
|
||||
</button>
|
||||
<button mat-menu-item (click)="changeTarget(element)">
|
||||
Change main ruleset
|
||||
</button>
|
||||
<button mat-menu-item (click)="cloneDelegateRuleset(element)">
|
||||
Clone delegate ruleset
|
||||
</button>
|
||||
<button mat-menu-item (click)="delete(element)">
|
||||
Delete
|
||||
</button>
|
||||
</mat-menu>
|
||||
</td>
|
||||
</ng-container>
|
||||
<tr mat-header-row *matHeaderRowDef="allDisplayedColumns"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: allDisplayedColumns"></tr>
|
||||
</table>
|
||||
|
||||
<mat-paginator
|
||||
[pageSizeOptions]="[10, 20, 50, 100, 250, 500]"
|
||||
showFirstLastButtons
|
||||
></mat-paginator>
|
||||
</mat-card-content>
|
||||
</mat-card>
|
||||
|
||||
<ng-template #empty>
|
||||
<div class="cc-display-1" fxLayout="column" fxLayoutAlign=" center">
|
||||
Routing rules not found
|
||||
</div>
|
||||
</ng-template>
|
@ -0,0 +1,34 @@
|
||||
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: `<dsh-routing-rules-list></dsh-routing-rules-list>`,
|
||||
})
|
||||
class HostComponent {}
|
||||
|
||||
describe('RoutingRulesListComponent', () => {
|
||||
let fixture: ComponentFixture<HostComponent>;
|
||||
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();
|
||||
});
|
||||
});
|
@ -0,0 +1,149 @@
|
||||
import {
|
||||
ChangeDetectionStrategy,
|
||||
Component,
|
||||
EventEmitter,
|
||||
Inject,
|
||||
Input,
|
||||
Output,
|
||||
ViewChild,
|
||||
} from '@angular/core';
|
||||
import { MatDialog } from '@angular/material/dialog';
|
||||
import { MatPaginator } from '@angular/material/paginator';
|
||||
import { MatTableDataSource } from '@angular/material/table';
|
||||
import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy';
|
||||
import { combineLatest, ReplaySubject } from 'rxjs';
|
||||
import { filter, map, shareReplay, startWith, switchMap } from 'rxjs/operators';
|
||||
|
||||
import { ConfirmActionDialogComponent } from '../../../../components/confirm-action-dialog';
|
||||
import { handleError } from '../../../../utils/operators/handle-error';
|
||||
import { ErrorService } from '../../../shared/services/error';
|
||||
import { RoutingRulesService } from '../../../thrift-services';
|
||||
import { DialogConfig, DIALOG_CONFIG } from '../../../tokens';
|
||||
import { ChangeDelegateRulesetDialogComponent } from '../change-delegate-ruleset-dialog';
|
||||
import { ChangeTargetDialogComponent } from '../change-target-dialog';
|
||||
|
||||
type DelegateId = {
|
||||
parentRefId: number;
|
||||
delegateIdx: number;
|
||||
};
|
||||
|
||||
@UntilDestroy()
|
||||
@Component({
|
||||
selector: 'cc-routing-rules-list',
|
||||
templateUrl: 'routing-rules-list.component.html',
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class RoutingRulesListComponent<T extends { [N in PropertyKey]: any } & DelegateId = any> {
|
||||
@Input() displayedColumns: { key: keyof T; name: string }[];
|
||||
|
||||
@Input() set data(data: T[]) {
|
||||
this.data$.next(data);
|
||||
}
|
||||
private data$ = new ReplaySubject<T[]>(1);
|
||||
|
||||
@Output() toDetails = new EventEmitter<DelegateId>();
|
||||
|
||||
@ViewChild(MatPaginator) set paginator(paginator: MatPaginator) {
|
||||
this.paginator$.next(paginator);
|
||||
}
|
||||
private paginator$ = new ReplaySubject<MatPaginator>(1);
|
||||
|
||||
dataSource$ = combineLatest([
|
||||
this.data$,
|
||||
this.paginator$.pipe(startWith<any, null>(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);
|
||||
}
|
||||
|
||||
constructor(
|
||||
private dialog: MatDialog,
|
||||
private errorService: ErrorService,
|
||||
private routingRulesService: RoutingRulesService,
|
||||
@Inject(DIALOG_CONFIG) private dialogConfig: DialogConfig
|
||||
) {}
|
||||
|
||||
getColumnsKeys(col) {
|
||||
return col.key;
|
||||
}
|
||||
|
||||
changeDelegateRuleset(delegateId: DelegateId) {
|
||||
this.dialog
|
||||
.open(ChangeDelegateRulesetDialogComponent, {
|
||||
...this.dialogConfig.medium,
|
||||
data: {
|
||||
mainRulesetRefID: delegateId.parentRefId,
|
||||
delegateIdx: delegateId.delegateIdx,
|
||||
},
|
||||
})
|
||||
.afterClosed()
|
||||
.pipe(handleError(this.errorService.error), untilDestroyed(this))
|
||||
.subscribe();
|
||||
}
|
||||
|
||||
changeTarget(delegateId: DelegateId) {
|
||||
this.dialog
|
||||
.open(ChangeTargetDialogComponent, {
|
||||
...this.dialogConfig.medium,
|
||||
data: {
|
||||
mainRulesetRefID: delegateId.parentRefId,
|
||||
delegateIdx: delegateId.delegateIdx,
|
||||
},
|
||||
})
|
||||
.afterClosed()
|
||||
.pipe(untilDestroyed(this))
|
||||
.subscribe({ error: this.errorService.error });
|
||||
}
|
||||
|
||||
cloneDelegateRuleset(delegateId: DelegateId) {
|
||||
this.dialog
|
||||
.open(ConfirmActionDialogComponent, { data: { title: 'Clone delegate ruleset' } })
|
||||
.afterClosed()
|
||||
.pipe(
|
||||
filter((r) => r === 'confirm'),
|
||||
switchMap(() =>
|
||||
this.routingRulesService.cloneDelegateRuleset({
|
||||
mainRulesetRefID: delegateId.parentRefId,
|
||||
delegateIdx: delegateId.delegateIdx,
|
||||
})
|
||||
),
|
||||
untilDestroyed(this)
|
||||
)
|
||||
.subscribe({ error: this.errorService.error });
|
||||
}
|
||||
|
||||
delete(delegateId: DelegateId) {
|
||||
this.dialog
|
||||
.open(ConfirmActionDialogComponent, { data: { title: 'Delete delegate' } })
|
||||
.afterClosed()
|
||||
.pipe(
|
||||
filter((r) => r === 'confirm'),
|
||||
switchMap(() =>
|
||||
this.routingRulesService.deleteDelegate({
|
||||
mainRulesetRefID: delegateId.parentRefId,
|
||||
delegateIdx: delegateId.delegateIdx,
|
||||
})
|
||||
),
|
||||
untilDestroyed(this)
|
||||
)
|
||||
.subscribe({ error: this.errorService.error });
|
||||
}
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { NgModule } from '@angular/core';
|
||||
import { FlexLayoutModule } from '@angular/flex-layout';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
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 { RoutingRulesListComponent } from './routing-rules-list.component';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
CommonModule,
|
||||
MatMenuModule,
|
||||
MatCardModule,
|
||||
MatTableModule,
|
||||
MatPaginatorModule,
|
||||
MatTableModule,
|
||||
MatIconModule,
|
||||
FlexLayoutModule,
|
||||
MatButtonModule,
|
||||
],
|
||||
declarations: [RoutingRulesListComponent],
|
||||
exports: [RoutingRulesListComponent],
|
||||
})
|
||||
export class RoutingRulesListModule {}
|
@ -4,7 +4,7 @@ import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
|
||||
import { of } from 'rxjs';
|
||||
import { startWith, switchMap, take } from 'rxjs/operators';
|
||||
|
||||
import { DomainTypedManager, PaymentRoutingRulesService } from '../../../../thrift-services';
|
||||
import { RoutingRulesService, TerminalService } from '../../../../thrift-services';
|
||||
import { Predicate } from '../../../../thrift-services/damsel/gen-model/domain';
|
||||
import { AddShopPaymentRoutingRuleDialogComponent } from './add-shop-payment-routing-rule-dialog.component';
|
||||
|
||||
@ -36,8 +36,8 @@ export class AddShopPaymentRoutingRuleDialogService {
|
||||
constructor(
|
||||
private fb: FormBuilder,
|
||||
private dialogRef: MatDialogRef<AddShopPaymentRoutingRuleDialogComponent>,
|
||||
private paymentRoutingRulesService: PaymentRoutingRulesService,
|
||||
private domainTypedManager: DomainTypedManager,
|
||||
private paymentRoutingRulesService: RoutingRulesService,
|
||||
private terminalService: TerminalService,
|
||||
@Inject(MAT_DIALOG_DATA) public data: { partyID: string; refID: number }
|
||||
) {
|
||||
this.form
|
||||
@ -72,7 +72,7 @@ export class AddShopPaymentRoutingRuleDialogService {
|
||||
newTerminal,
|
||||
} = this.form.value;
|
||||
(terminalType === TerminalType.new
|
||||
? this.domainTypedManager.createTerminal({
|
||||
? this.terminalService.createTerminal({
|
||||
terminalName: newTerminal.name,
|
||||
terminalDescription: newTerminal.description,
|
||||
riskCoverage: newTerminal.riskCoverage,
|
||||
|
@ -6,7 +6,7 @@ import { map, pluck, shareReplay, switchMap, take } from 'rxjs/operators';
|
||||
import { handleError } from '../../../../utils/operators/handle-error';
|
||||
import { PartyService } from '../../../papi/party.service';
|
||||
import { ErrorService } from '../../../shared/services/error';
|
||||
import { PaymentRoutingRulesService as PaymentRoutingRulesDamselService } from '../../../thrift-services';
|
||||
import { RoutingRulesService as PaymentRoutingRulesDamselService } from '../../../thrift-services';
|
||||
|
||||
@Injectable()
|
||||
export class ShopPaymentRoutingRulesetService {
|
||||
|
@ -1,5 +1,5 @@
|
||||
<div [formGroup]="form" fxLayout="column" fxLayoutGap="24px">
|
||||
<div class="cc-title">Target Ruleset</div>
|
||||
<div class="cc-title">Change Main Ruleset</div>
|
||||
|
||||
<div fxLayout="column" fxLayoutGap="39px">
|
||||
<mat-radio-group fxLayout formControlName="target">
|
||||
@ -39,7 +39,7 @@
|
||||
</ng-container>
|
||||
</div>
|
||||
<mat-form-field *ngIf="form.controls.target.value === target.manual">
|
||||
<mat-label>Payment Routing Ruleset</mat-label>
|
||||
<mat-label>Main Ruleset</mat-label>
|
||||
<mat-select formControlName="mainRulesetRefID" required>
|
||||
<mat-option *ngFor="let i of rulesets$ | async" [value]="i.ref.id">
|
||||
#{{ i.ref.id }} {{ i.data.name }}
|
||||
|
@ -15,7 +15,7 @@ import { PaymentInstitutionObject } from 'src/app/thrift-services/damsel/gen-mod
|
||||
|
||||
import { ComponentChanges } from '@cc/app/shared/utils';
|
||||
|
||||
import { PaymentRoutingRulesService } from '../../../thrift-services';
|
||||
import { RoutingRulesService } from '../../../thrift-services';
|
||||
import { Target } from './types/target';
|
||||
import { TargetRuleset } from './types/target-ruleset';
|
||||
|
||||
@ -47,7 +47,7 @@ export class TargetRulesetFormComponent implements OnChanges {
|
||||
constructor(
|
||||
private fb: FormBuilder,
|
||||
private domainService: DomainCacheService,
|
||||
private paymentRoutingRulesService: PaymentRoutingRulesService
|
||||
private paymentRoutingRulesService: RoutingRulesService
|
||||
) {
|
||||
this.form.controls.target.valueChanges
|
||||
.pipe(startWith(this.form.value.target), untilDestroyed(this))
|
||||
|
@ -4,10 +4,7 @@ import { progress } from '@rbkmoney/partial-fetcher/dist/progress';
|
||||
import { merge, Observable, Subject } from 'rxjs';
|
||||
import { map, shareReplay, switchMap } from 'rxjs/operators';
|
||||
|
||||
import {
|
||||
AddDecisionToProvider,
|
||||
DomainTypedManager,
|
||||
} from '../../../../../../thrift-services/damsel';
|
||||
import { AddDecisionToProvider, ProviderService } from '../../../../../../thrift-services/damsel';
|
||||
import { DomainCacheService } from '../../../../../../thrift-services/damsel/domain-cache.service';
|
||||
import {
|
||||
PartyID,
|
||||
@ -35,7 +32,7 @@ export class AddTerminalDecisionService {
|
||||
terminalID: this.terminalForm.value.id,
|
||||
})),
|
||||
switchMap((params) =>
|
||||
this.domainTypedManager.getProviderFromParams<AddDecisionToProvider>(params)
|
||||
this.providerService.getProviderFromParams<AddDecisionToProvider>(params)
|
||||
),
|
||||
switchMap(([params, providerObject]) =>
|
||||
this.domainCacheService.commit(addDecisionToProviderCommit(providerObject, params))
|
||||
@ -47,7 +44,7 @@ export class AddTerminalDecisionService {
|
||||
|
||||
constructor(
|
||||
private domainCacheService: DomainCacheService,
|
||||
private domainTypedManager: DomainTypedManager,
|
||||
private providerService: ProviderService,
|
||||
private fb: FormBuilder
|
||||
) {
|
||||
this.terminalAdded$.subscribe();
|
||||
|
@ -7,7 +7,7 @@ import { catchError, filter, map, shareReplay, switchMap } from 'rxjs/operators'
|
||||
|
||||
import { ConfirmActionDialogComponent } from '@cc/components/confirm-action-dialog';
|
||||
|
||||
import { DomainTypedManager } from '../../../../../thrift-services/damsel';
|
||||
import { ProviderService } from '../../../../../thrift-services/damsel';
|
||||
import { DomainCacheService } from '../../../../../thrift-services/damsel/domain-cache.service';
|
||||
import { createRemoveTerminalFromShopCommit } from '../../../../../thrift-services/damsel/operations/create-remove-terminal-from-shop-commit';
|
||||
import { RemoveTerminalFromShopParams } from '../../../../../thrift-services/damsel/operations/remove-terminal-from-shop-params';
|
||||
@ -40,7 +40,7 @@ export class RemoveTerminalDecisionService {
|
||||
])
|
||||
),
|
||||
switchMap(([params]) =>
|
||||
this.domainTypedManager.getProviderFromParams<RemoveTerminalFromShopParams>(params)
|
||||
this.providerService.getProviderFromParams<RemoveTerminalFromShopParams>(params)
|
||||
),
|
||||
map(([params, providerObject]) =>
|
||||
createRemoveTerminalFromShopCommit(providerObject, params)
|
||||
@ -65,7 +65,7 @@ export class RemoveTerminalDecisionService {
|
||||
private dialog: MatDialog,
|
||||
private snackBar: MatSnackBar,
|
||||
private domainCacheService: DomainCacheService,
|
||||
private domainTypedManager: DomainTypedManager
|
||||
private providerService: ProviderService
|
||||
) {
|
||||
this.terminalRemoved$.subscribe();
|
||||
this.error$.subscribe(() => {
|
||||
|
@ -4,7 +4,7 @@ import { Observable } from 'rxjs';
|
||||
import { KeycloakTokenInfoService } from '../../keycloak-token-info.service';
|
||||
import { toGenReference } from '../converters';
|
||||
import { PartyID } from '../damsel/gen-model/domain';
|
||||
import { ThriftService } from '../thrift-service';
|
||||
import { ThriftService } from '../services/thrift/thrift-service';
|
||||
import {
|
||||
QuestionaryID,
|
||||
QuestionaryParams,
|
||||
|
@ -3,7 +3,7 @@ import { Observable } from 'rxjs';
|
||||
import { switchMap } from 'rxjs/operators';
|
||||
|
||||
import { KeycloakTokenInfoService } from '../../keycloak-token-info.service';
|
||||
import { ThriftService } from '../thrift-service';
|
||||
import { ThriftService } from '../services/thrift/thrift-service';
|
||||
import {
|
||||
Claim,
|
||||
ClaimID,
|
||||
|
@ -1,24 +0,0 @@
|
||||
import metadata from '../../../assets/meta-damsel.json';
|
||||
import { createThriftInstanceUtils } from '../thrift-instance';
|
||||
import * as base from './gen-nodejs/base_types';
|
||||
import * as claim_management from './gen-nodejs/claim_management_types';
|
||||
import * as domain_config from './gen-nodejs/domain_config_types';
|
||||
import * as domain from './gen-nodejs/domain_types';
|
||||
import * as geo_ip from './gen-nodejs/geo_ip_types';
|
||||
import * as merch_stat from './gen-nodejs/merch_stat_types';
|
||||
import * as payment_processing from './gen-nodejs/payment_processing_types';
|
||||
|
||||
const namespaces = {
|
||||
base,
|
||||
domain,
|
||||
domain_config,
|
||||
claim_management,
|
||||
geo_ip,
|
||||
merch_stat,
|
||||
payment_processing,
|
||||
};
|
||||
|
||||
export const {
|
||||
createThriftInstance: createDamselInstance,
|
||||
thriftInstanceToObject: damselInstanceToObject,
|
||||
} = createThriftInstanceUtils(metadata, namespaces);
|
@ -2,21 +2,22 @@ import { NgModule } from '@angular/core';
|
||||
|
||||
import { ClaimManagementService } from './claim-management.service';
|
||||
import { DomainCacheService } from './domain-cache.service';
|
||||
import { DomainTypedManager } from './domain-typed-manager';
|
||||
import { DomainService } from './domain.service';
|
||||
import { MerchantStatisticsService } from './merchant-statistics.service';
|
||||
import { PaymentProcessingService } from './payment-processing.service';
|
||||
import { PaymentRoutingRulesService } from './payment-routing-rules.service';
|
||||
import { ProviderService } from './provider.service';
|
||||
import { RoutingRulesModule } from './routing-rules';
|
||||
import { TerminalModule } from './terminal';
|
||||
|
||||
@NgModule({
|
||||
imports: [RoutingRulesModule, TerminalModule],
|
||||
providers: [
|
||||
DomainService,
|
||||
DomainTypedManager,
|
||||
ProviderService,
|
||||
PaymentProcessingService,
|
||||
MerchantStatisticsService,
|
||||
DomainCacheService,
|
||||
ClaimManagementService,
|
||||
PaymentRoutingRulesService,
|
||||
],
|
||||
})
|
||||
export class DamselModule {}
|
||||
|
@ -1,16 +1,15 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy';
|
||||
import { BehaviorSubject, Observable, of, ReplaySubject } from 'rxjs';
|
||||
import { map, pluck, shareReplay, startWith, switchMap, take, tap } from 'rxjs/operators';
|
||||
import type { Int64 } from 'thrift-ts';
|
||||
import { map, pluck, share, shareReplay, startWith, switchMap, take, tap } from 'rxjs/operators';
|
||||
|
||||
import { getUnionKey } from '@cc/utils/get-union-key';
|
||||
|
||||
import { toGenReference } from '../converters';
|
||||
import { createDamselInstance, damselInstanceToObject } from './create-damsel-instance';
|
||||
import { DomainService } from './domain.service';
|
||||
import { Domain, DomainObject } from './gen-model/domain';
|
||||
import { Commit, Snapshot, Version } from './gen-model/domain_config';
|
||||
import { createDamselInstance, damselInstanceToObject } from './utils/create-damsel-instance';
|
||||
|
||||
@UntilDestroy()
|
||||
@Injectable()
|
||||
@ -21,7 +20,7 @@ export class DomainCacheService {
|
||||
domain: Observable<Domain>;
|
||||
snapshot$: Observable<Snapshot>;
|
||||
domain$: Observable<Domain>;
|
||||
version$: Observable<Int64>;
|
||||
version$: Observable<number>;
|
||||
get isLoading$(): Observable<boolean> {
|
||||
return this._isLoading$.asObservable();
|
||||
}
|
||||
@ -43,7 +42,7 @@ export class DomainCacheService {
|
||||
shareReplay(1)
|
||||
);
|
||||
this.domain$ = this.snapshot$.pipe(pluck('domain'));
|
||||
this.version$ = this.snapshot$.pipe(pluck('version'));
|
||||
this.version$ = this.snapshot$.pipe(pluck('version')) as Observable<any>;
|
||||
|
||||
this.snapshot.pipe(untilDestroyed(this)).subscribe();
|
||||
}
|
||||
@ -61,17 +60,26 @@ export class DomainCacheService {
|
||||
)
|
||||
);
|
||||
|
||||
commit = (commit: Commit, version?: Version) => {
|
||||
return (version ? of(version) : this.version$).pipe(
|
||||
take(1),
|
||||
commit = (commit: Commit, version?: Version | number, reload = true) => {
|
||||
const version$ = version ? of(version) : this.version$.pipe(take(1));
|
||||
return version$.pipe(
|
||||
switchMap((v) =>
|
||||
this.dmtService.commit(
|
||||
createDamselInstance('domain_config', 'Version', v),
|
||||
createDamselInstance('domain_config', 'Version', v as Version),
|
||||
createDamselInstance('domain_config', 'Commit', commit)
|
||||
)
|
||||
),
|
||||
map((v) => damselInstanceToObject('domain_config', 'Version', v)),
|
||||
tap(() => this.forceReload())
|
||||
tap(() => reload && this.forceReload()),
|
||||
share()
|
||||
);
|
||||
};
|
||||
|
||||
sequenseCommits([commit, ...otherCommits]: Commit[], version?: Version | number) {
|
||||
return otherCommits.length
|
||||
? this.commit(commit, version, false).pipe(
|
||||
switchMap((v) => this.sequenseCommits(otherCommits, v))
|
||||
)
|
||||
: this.commit(commit, version);
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,7 @@ import { Injectable, NgZone } from '@angular/core';
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
import { KeycloakTokenInfoService } from '../../keycloak-token-info.service';
|
||||
import { ThriftService } from '../thrift-service';
|
||||
import { ThriftService } from '../services/thrift/thrift-service';
|
||||
import { Commit, Limit, Reference, Snapshot, Version } from './gen-model/domain_config';
|
||||
import * as Repository from './gen-nodejs/Repository';
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
export * from './operations';
|
||||
export * from './domain-typed-manager';
|
||||
export * from './domain.service';
|
||||
export * from './get-thrift-instance';
|
||||
export * from './create-damsel-instance';
|
||||
export * from './utils/create-damsel-instance';
|
||||
export * from './damsel.module';
|
||||
export * from './payment-routing-rules.service';
|
||||
export * from './routing-rules';
|
||||
export * from './services';
|
||||
export * from './terminal';
|
||||
export * from './provider.service';
|
||||
|
@ -3,11 +3,11 @@ import { Observable } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
|
||||
import { KeycloakTokenInfoService } from '../../keycloak-token-info.service';
|
||||
import { ThriftService } from '../thrift-service';
|
||||
import { createDamselInstance, damselInstanceToObject } from './create-damsel-instance';
|
||||
import { ThriftService } from '../services/thrift/thrift-service';
|
||||
import { StatRequest, StatResponse } from './gen-model/merch_stat';
|
||||
import * as MerchantStatistics from './gen-nodejs/MerchantStatistics';
|
||||
import { StatRequest as ThriftStatRequest } from './gen-nodejs/merch_stat_types';
|
||||
import { createDamselInstance, damselInstanceToObject } from './utils/create-damsel-instance';
|
||||
|
||||
@Injectable()
|
||||
export class MerchantStatisticsService extends ThriftService {
|
||||
|
@ -4,8 +4,7 @@ import { Observable, timer } from 'rxjs';
|
||||
import { first, map, share, switchMap } from 'rxjs/operators';
|
||||
|
||||
import { KeycloakTokenInfoService } from '../../keycloak-token-info.service';
|
||||
import { ThriftService } from '../thrift-service';
|
||||
import { createDamselInstance, damselInstanceToObject } from './create-damsel-instance';
|
||||
import { ThriftService } from '../services/thrift/thrift-service';
|
||||
import {
|
||||
InvoiceID,
|
||||
InvoicePaymentChargeback,
|
||||
@ -29,6 +28,7 @@ import {
|
||||
InvoiceRepairScenario as InvoiceRepairScenarioObject,
|
||||
UserInfo as UserInfoObject,
|
||||
} from './gen-nodejs/payment_processing_types';
|
||||
import { createDamselInstance, damselInstanceToObject } from './utils/create-damsel-instance';
|
||||
|
||||
@Injectable()
|
||||
export class PaymentProcessingService extends ThriftService {
|
||||
|
@ -5,16 +5,11 @@ import { map, switchMap, take } from 'rxjs/operators';
|
||||
import { DomainCacheService } from './domain-cache.service';
|
||||
import { ProviderObject } from './gen-model/domain';
|
||||
import { Version } from './gen-model/domain_config';
|
||||
import {
|
||||
AddDecisionToProvider,
|
||||
addDecisionToProviderCommit,
|
||||
CreateTerminalParams,
|
||||
getCreateTerminalCommit,
|
||||
} from './operations';
|
||||
import { AddDecisionToProvider, addDecisionToProviderCommit } from './operations';
|
||||
import { findDomainObject } from './operations/utils';
|
||||
|
||||
@Injectable()
|
||||
export class DomainTypedManager {
|
||||
export class ProviderService {
|
||||
constructor(private domainCacheService: DomainCacheService) {}
|
||||
|
||||
getProviderFromParams<T extends { providerID: number }>(
|
||||
@ -40,20 +35,4 @@ export class DomainTypedManager {
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated select in separate service
|
||||
*/
|
||||
createTerminal(params: CreateTerminalParams): Observable<number> {
|
||||
let newTerminalID = null;
|
||||
return this.domainCacheService.getObjects('terminal').pipe(
|
||||
take(1),
|
||||
switchMap((terminalObjects) => {
|
||||
const { commit, id } = getCreateTerminalCommit(terminalObjects, params);
|
||||
newTerminalID = id;
|
||||
return this.domainCacheService.commit(commit);
|
||||
}),
|
||||
map(() => newTerminalID)
|
||||
);
|
||||
}
|
||||
}
|
2
src/app/thrift-services/damsel/routing-rules/index.ts
Normal file
2
src/app/thrift-services/damsel/routing-rules/index.ts
Normal file
@ -0,0 +1,2 @@
|
||||
export * from './routing-rules.module';
|
||||
export * from './routing-rules.service';
|
@ -0,0 +1,8 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
|
||||
import { RoutingRulesService } from './routing-rules.service';
|
||||
|
||||
@NgModule({
|
||||
providers: [RoutingRulesService],
|
||||
})
|
||||
export class RoutingRulesModule {}
|
@ -1,19 +1,21 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import cloneDeep from 'lodash-es/cloneDeep';
|
||||
import { combineLatest, Observable } from 'rxjs';
|
||||
import { map, shareReplay, switchMap, take } from 'rxjs/operators';
|
||||
import { map, pluck, shareReplay, switchMap, take } from 'rxjs/operators';
|
||||
|
||||
import { DomainCacheService } from './domain-cache.service';
|
||||
import { createNextId } from '../../utils/create-next-id';
|
||||
import { DomainCacheService } from '../domain-cache.service';
|
||||
import {
|
||||
Predicate,
|
||||
RoutingCandidate,
|
||||
RoutingDelegate,
|
||||
RoutingRulesObject,
|
||||
} from './gen-model/domain';
|
||||
import { Version } from './gen-model/domain_config';
|
||||
} from '../gen-model/domain';
|
||||
import { Version } from '../gen-model/domain_config';
|
||||
import { getDelegate } from './utils/get-delegate';
|
||||
|
||||
@Injectable()
|
||||
export class PaymentRoutingRulesService {
|
||||
export class RoutingRulesService {
|
||||
constructor(private domainService: DomainCacheService) {}
|
||||
|
||||
rulesets$: Observable<RoutingRulesObject[]> = this.domainService
|
||||
@ -25,7 +27,7 @@ export class PaymentRoutingRulesService {
|
||||
|
||||
nextRefID$ = this.rulesets$.pipe(
|
||||
map((rulesets) => rulesets.map(({ ref }) => ref.id)),
|
||||
map((ids) => Math.max(...ids) + 1)
|
||||
map(createNextId)
|
||||
);
|
||||
|
||||
getRuleset(refID: number): Observable<RoutingRulesObject> {
|
||||
@ -263,19 +265,16 @@ export class PaymentRoutingRulesService {
|
||||
|
||||
deleteDelegate({
|
||||
mainRulesetRefID,
|
||||
rulesetRefID,
|
||||
delegateIdx,
|
||||
}: {
|
||||
mainRulesetRefID: number;
|
||||
rulesetRefID: number;
|
||||
delegateIdx: number;
|
||||
}): Observable<Version> {
|
||||
return this.getRuleset(mainRulesetRefID).pipe(
|
||||
take(1),
|
||||
switchMap((mainRuleset) => {
|
||||
const newMainPaymentRoutingRuleset = cloneDeep(mainRuleset);
|
||||
newMainPaymentRoutingRuleset.data.decisions.delegates.splice(
|
||||
this.getDelegateIdx(mainRuleset, rulesetRefID),
|
||||
1
|
||||
);
|
||||
newMainPaymentRoutingRuleset.data.decisions.delegates.splice(delegateIdx, 1);
|
||||
return this.domainService.commit({
|
||||
ops: [
|
||||
{
|
||||
@ -290,15 +289,15 @@ export class PaymentRoutingRulesService {
|
||||
);
|
||||
}
|
||||
|
||||
changeDelegateRuleset({
|
||||
changeMainRuleset({
|
||||
previousMainRulesetRefID,
|
||||
mainRulesetRefID,
|
||||
rulesetID,
|
||||
delegateIdx,
|
||||
mainDelegateDescription,
|
||||
}: {
|
||||
previousMainRulesetRefID: number;
|
||||
mainRulesetRefID: number;
|
||||
rulesetID: number;
|
||||
delegateIdx: number;
|
||||
mainDelegateDescription?: string;
|
||||
}): Observable<Version> {
|
||||
return combineLatest([
|
||||
@ -309,7 +308,7 @@ export class PaymentRoutingRulesService {
|
||||
switchMap(([mainRuleset, previousMainRuleset]) => {
|
||||
const newPreviousMainRuleset = cloneDeep(previousMainRuleset);
|
||||
const [delegate] = newPreviousMainRuleset.data.decisions.delegates.splice(
|
||||
this.getDelegateIdx(previousMainRuleset, rulesetID),
|
||||
delegateIdx,
|
||||
1
|
||||
);
|
||||
const newMainPaymentRoutingRuleset = cloneDeep(mainRuleset);
|
||||
@ -340,9 +339,84 @@ export class PaymentRoutingRulesService {
|
||||
);
|
||||
}
|
||||
|
||||
private getDelegateIdx(ruleset: RoutingRulesObject, delegateRulesetRefId: number) {
|
||||
return ruleset.data.decisions.delegates.findIndex(
|
||||
(d) => d?.ruleset?.id === delegateRulesetRefId
|
||||
changeDelegateRuleset({
|
||||
mainRulesetRefID,
|
||||
delegateIdx,
|
||||
newDelegateRulesetRefID,
|
||||
description,
|
||||
}: {
|
||||
mainRulesetRefID: number;
|
||||
delegateIdx: number;
|
||||
newDelegateRulesetRefID: number;
|
||||
description?: string;
|
||||
}): Observable<Version> {
|
||||
return this.getRuleset(mainRulesetRefID).pipe(
|
||||
take(1),
|
||||
switchMap((mainRuleset) => {
|
||||
const newMainRuleset = cloneDeep(mainRuleset);
|
||||
newMainRuleset.data.decisions.delegates[
|
||||
delegateIdx
|
||||
].ruleset.id = newDelegateRulesetRefID;
|
||||
if (description !== undefined) {
|
||||
newMainRuleset.data.decisions.delegates[delegateIdx].description = description;
|
||||
}
|
||||
return this.domainService.commit({
|
||||
ops: [
|
||||
{
|
||||
update: {
|
||||
old_object: { routing_rules: mainRuleset },
|
||||
new_object: { routing_rules: newMainRuleset },
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
cloneDelegateRuleset({
|
||||
mainRulesetRefID,
|
||||
delegateIdx,
|
||||
}: {
|
||||
mainRulesetRefID: number;
|
||||
delegateIdx: number;
|
||||
}): Observable<Version> {
|
||||
return combineLatest([
|
||||
this.getRuleset(mainRulesetRefID),
|
||||
this.getRuleset(mainRulesetRefID).pipe(
|
||||
switchMap((r) => this.getRuleset(getDelegate(r, delegateIdx).ruleset.id))
|
||||
),
|
||||
this.nextRefID$,
|
||||
]).pipe(
|
||||
take(1),
|
||||
switchMap(([mainRuleset, delegateRuleset, nextRefID]) => {
|
||||
const newMainRuleset = cloneDeep(mainRuleset);
|
||||
getDelegate(newMainRuleset, delegateIdx).ruleset.id = nextRefID;
|
||||
const newDelegateRuleset = cloneDeep(delegateRuleset);
|
||||
newDelegateRuleset.ref.id = nextRefID;
|
||||
return this.domainService.sequenseCommits([
|
||||
{
|
||||
ops: [
|
||||
{
|
||||
insert: {
|
||||
object: { routing_rules: newDelegateRuleset },
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
ops: [
|
||||
{
|
||||
update: {
|
||||
old_object: { routing_rules: mainRuleset },
|
||||
new_object: { routing_rules: newMainRuleset },
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
]);
|
||||
}),
|
||||
pluck('1')
|
||||
);
|
||||
}
|
||||
|
@ -0,0 +1,8 @@
|
||||
import { RoutingDelegate, RoutingRulesObject } from '../../gen-model/domain';
|
||||
|
||||
export function getDelegate(
|
||||
ruleset: RoutingRulesObject,
|
||||
delegateIdx: number
|
||||
): RoutingDelegate | undefined {
|
||||
return ruleset?.data?.decisions?.delegates?.[delegateIdx];
|
||||
}
|
@ -5,9 +5,9 @@ import { EMPTY, merge, Subject } from 'rxjs';
|
||||
import { catchError, shareReplay, switchMap } from 'rxjs/operators';
|
||||
|
||||
import { DomainCacheService } from '../domain-cache.service';
|
||||
import { DomainTypedManager } from '../domain-typed-manager';
|
||||
import { editTerminalDecisionPropertyForShopCommit } from '../operations/edit-terminal-decision-property-for-shop-commit';
|
||||
import { EditTerminalDecisionPropertyParams } from '../operations/edit-terminal-decision-property-params';
|
||||
import { ProviderService } from '../provider.service';
|
||||
|
||||
@Injectable()
|
||||
export class EditTerminalDecisionPropertyForShopService {
|
||||
@ -17,9 +17,7 @@ export class EditTerminalDecisionPropertyForShopService {
|
||||
|
||||
edited$ = this.editProperty$.pipe(
|
||||
switchMap((params) =>
|
||||
this.domainTypedManager.getProviderFromParams<EditTerminalDecisionPropertyParams>(
|
||||
params
|
||||
)
|
||||
this.providerService.getProviderFromParams<EditTerminalDecisionPropertyParams>(params)
|
||||
),
|
||||
switchMap(([params, provider]) => {
|
||||
return this.domainCacheService
|
||||
@ -39,7 +37,7 @@ export class EditTerminalDecisionPropertyForShopService {
|
||||
constructor(
|
||||
private domainCacheService: DomainCacheService,
|
||||
private snackBar: MatSnackBar,
|
||||
private domainTypedManager: DomainTypedManager
|
||||
private providerService: ProviderService
|
||||
) {
|
||||
this.error$.subscribe(() => {
|
||||
this.snackBar.open('An error occurred while editing providerObject');
|
||||
|
2
src/app/thrift-services/damsel/terminal/index.ts
Normal file
2
src/app/thrift-services/damsel/terminal/index.ts
Normal file
@ -0,0 +1,2 @@
|
||||
export * from './terminal.service';
|
||||
export * from './terminal.module';
|
@ -0,0 +1,8 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
|
||||
import { TerminalService } from './terminal.service';
|
||||
|
||||
@NgModule({
|
||||
providers: [TerminalService],
|
||||
})
|
||||
export class TerminalModule {}
|
@ -0,0 +1,20 @@
|
||||
import { TestBed } from '@angular/core/testing';
|
||||
|
||||
import { TerminalService } from './terminal.service';
|
||||
|
||||
describe('TerminalService', () => {
|
||||
let service: TerminalService;
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [],
|
||||
providers: [TerminalService],
|
||||
});
|
||||
|
||||
service = TestBed.inject(TerminalService);
|
||||
});
|
||||
|
||||
it('should be created', () => {
|
||||
expect(service).toBeTruthy();
|
||||
});
|
||||
});
|
21
src/app/thrift-services/damsel/terminal/terminal.service.ts
Normal file
21
src/app/thrift-services/damsel/terminal/terminal.service.ts
Normal file
@ -0,0 +1,21 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Observable } from 'rxjs';
|
||||
import { mapTo, switchMap, take } from 'rxjs/operators';
|
||||
|
||||
import { DomainCacheService } from '../domain-cache.service';
|
||||
import { CreateTerminalParams, getCreateTerminalCommit } from '../operations';
|
||||
|
||||
@Injectable()
|
||||
export class TerminalService {
|
||||
constructor(private domainCacheService: DomainCacheService) {}
|
||||
|
||||
createTerminal(params: CreateTerminalParams): Observable<number> {
|
||||
return this.domainCacheService.getObjects('terminal').pipe(
|
||||
take(1),
|
||||
switchMap((terminalObjects) => {
|
||||
const { commit, id } = getCreateTerminalCommit(terminalObjects, params);
|
||||
return this.domainCacheService.commit(commit).pipe(mapTo(id));
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
import metadata from '../../../../assets/meta-damsel.json';
|
||||
import { createThriftInstanceUtils } from '../../utils/thrift-instance';
|
||||
import * as base from '../gen-nodejs/base_types';
|
||||
import * as claim_management from '../gen-nodejs/claim_management_types';
|
||||
import * as domain_config from '../gen-nodejs/domain_config_types';
|
||||
import * as domain from '../gen-nodejs/domain_types';
|
||||
import * as geo_ip from '../gen-nodejs/geo_ip_types';
|
||||
import * as merch_stat from '../gen-nodejs/merch_stat_types';
|
||||
import * as payment_processing from '../gen-nodejs/payment_processing_types';
|
||||
|
||||
const namespaces = {
|
||||
base,
|
||||
domain,
|
||||
domain_config,
|
||||
claim_management,
|
||||
geo_ip,
|
||||
merch_stat,
|
||||
payment_processing,
|
||||
};
|
||||
|
||||
export const {
|
||||
createThriftInstance: createDamselInstance,
|
||||
thriftInstanceToObject: damselInstanceToObject,
|
||||
} = createThriftInstanceUtils(metadata, namespaces);
|
@ -2,7 +2,7 @@ import { Injectable, NgZone } from '@angular/core';
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
import { KeycloakTokenInfoService } from '../../keycloak-token-info.service';
|
||||
import { ThriftService } from '../thrift-service';
|
||||
import { ThriftService } from '../services/thrift/thrift-service';
|
||||
import { SearchHit } from './gen-model/deanonimus';
|
||||
import * as Deanonimus from './gen-nodejs/Deanonimus';
|
||||
|
||||
|
@ -2,7 +2,7 @@ import { Injectable, NgZone } from '@angular/core';
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
import { KeycloakTokenInfoService } from '../../keycloak-token-info.service';
|
||||
import { ThriftService } from '../thrift-service';
|
||||
import { ThriftService } from '../services/thrift/thrift-service';
|
||||
import { Timestamp } from './gen-model/base';
|
||||
import {
|
||||
FileData,
|
||||
|
@ -2,7 +2,7 @@ import { Injectable, NgZone } from '@angular/core';
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
import { KeycloakTokenInfoService } from '../../keycloak-token-info.service';
|
||||
import { ThriftService } from '../thrift-service';
|
||||
import { ThriftService } from '../services/thrift/thrift-service';
|
||||
import { DepositParams } from './gen-model/fistful_admin';
|
||||
import * as FistfulAdmin from './gen-nodejs/FistfulAdmin';
|
||||
import { DepositParams as DepositParamsObject } from './gen-nodejs/fistful_admin_types';
|
||||
|
@ -6,7 +6,7 @@ import { map } from 'rxjs/operators';
|
||||
import { SearchFormParams } from '../../deposits/search-form/search-form-params';
|
||||
import { KeycloakTokenInfoService } from '../../keycloak-token-info.service';
|
||||
import { QueryDSL } from '../../query-dsl';
|
||||
import { ThriftService } from '../thrift-service';
|
||||
import { ThriftService } from '../services/thrift/thrift-service';
|
||||
import { StatDeposit, StatRequest } from './gen-model/fistful_stat';
|
||||
import * as FistfulStatistics from './gen-nodejs/FistfulStatistics';
|
||||
import { StatRequest as ThriftStatRequest } from './gen-nodejs/fistful_stat_types';
|
||||
|
@ -2,7 +2,7 @@ import { Injectable, NgZone } from '@angular/core';
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
import { KeycloakTokenInfoService } from '../../keycloak-token-info.service';
|
||||
import { ThriftService } from '../thrift-service';
|
||||
import { ThriftService } from '../services/thrift/thrift-service';
|
||||
import { RepairScenario, SessionID } from './gen-model/withdrawal_session';
|
||||
import * as Repairer from './gen-nodejs/Repairer';
|
||||
import { RepairScenario as RepairScenarioObject } from './gen-nodejs/withdrawal_session_types';
|
||||
|
@ -1,6 +1,6 @@
|
||||
export * from './thrift-service';
|
||||
export * from './filters';
|
||||
export * from './thrift-instance';
|
||||
export * from './utils/thrift-instance';
|
||||
export * from './utils/get-thrift-instance';
|
||||
export * from './ank';
|
||||
export * from './file-storage';
|
||||
export * from './messages';
|
||||
|
@ -2,7 +2,7 @@ import { Injectable, NgZone } from '@angular/core';
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
import { KeycloakTokenInfoService } from '../../keycloak-token-info.service';
|
||||
import { ThriftService } from '../thrift-service';
|
||||
import { ThriftService } from '../services/thrift/thrift-service';
|
||||
import { Namespace } from './gen-model/base';
|
||||
import { Machine, MachineDescriptor, Reference } from './gen-model/state_processing';
|
||||
import * as Automaton from './gen-nodejs/Automaton';
|
||||
|
@ -2,7 +2,7 @@ import { Injectable, NgZone } from '@angular/core';
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
import { KeycloakTokenInfoService } from '../../keycloak-token-info.service';
|
||||
import { ThriftService } from '../thrift-service';
|
||||
import { ThriftService } from '../services/thrift/thrift-service';
|
||||
import {
|
||||
Conversation,
|
||||
ConversationFilter,
|
||||
|
@ -3,7 +3,7 @@ import { Observable } from 'rxjs';
|
||||
import { timeout } from 'rxjs/operators';
|
||||
import connectClient from 'woody_js';
|
||||
|
||||
import { KeycloakTokenInfoService } from '../keycloak-token-info.service';
|
||||
import { KeycloakTokenInfoService } from '../../../keycloak-token-info.service';
|
||||
|
||||
type Exception<N = string, T = {}> = {
|
||||
name: N;
|
@ -3,7 +3,7 @@ import { Observable } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
|
||||
import { KeycloakTokenInfoService } from '../../keycloak-token-info.service';
|
||||
import { ThriftService } from '../thrift-service';
|
||||
import { ThriftService } from '../services/thrift/thrift-service';
|
||||
import { ID } from './gen-model/base';
|
||||
import { ChargebackData, ChargebackEvent, ChargebackFilter } from './gen-model/skipper';
|
||||
import * as Skipper from './gen-nodejs/Skipper';
|
||||
|
@ -1,5 +1,5 @@
|
||||
import metadata from '../../../assets/meta-skipper.json';
|
||||
import { createThriftInstanceUtils } from '../thrift-instance';
|
||||
import { createThriftInstanceUtils } from '../utils/thrift-instance';
|
||||
import * as base from './gen-nodejs/base_types';
|
||||
import * as chargeback from './gen-nodejs/chargeback_types';
|
||||
import * as skipper from './gen-nodejs/skipper_types';
|
||||
|
5
src/app/thrift-services/utils/create-next-id.ts
Normal file
5
src/app/thrift-services/utils/create-next-id.ts
Normal file
@ -0,0 +1,5 @@
|
||||
// TODO: numeric overflow, need logic to use the freed
|
||||
// TODO: return Int64
|
||||
export function createNextId(ids: number[]) {
|
||||
return Math.max(...ids) + 1;
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
import * as BaseTypes from './gen-nodejs/base_types';
|
||||
import * as DomainConfigTypes from './gen-nodejs/domain_config_types';
|
||||
import * as DomainTypes from './gen-nodejs/domain_types';
|
||||
import * as BaseTypes from '../damsel/gen-nodejs/base_types';
|
||||
import * as DomainConfigTypes from '../damsel/gen-nodejs/domain_config_types';
|
||||
import * as DomainTypes from '../damsel/gen-nodejs/domain_types';
|
||||
|
||||
export const SupportedNamespaces = {
|
||||
base: BaseTypes,
|
24
src/app/tokens.ts
Normal file
24
src/app/tokens.ts
Normal file
@ -0,0 +1,24 @@
|
||||
import { InjectionToken } from '@angular/core';
|
||||
import { MatDialogConfig } from '@angular/material/dialog';
|
||||
|
||||
export const LAYOUT_GAP = new InjectionToken<string>('layoutGap');
|
||||
|
||||
export const SEARCH_LIMIT = new InjectionToken<number>('searchLimit');
|
||||
export const DEFAULT_SEARCH_LIMIT = 10;
|
||||
|
||||
export type DialogConfig = {
|
||||
small: MatDialogConfig;
|
||||
medium: MatDialogConfig;
|
||||
large: MatDialogConfig;
|
||||
};
|
||||
export const DIALOG_CONFIG = new InjectionToken<DialogConfig>('dialogConfig');
|
||||
const baseConfig: MatDialogConfig = {
|
||||
maxHeight: '90vh',
|
||||
disableClose: true,
|
||||
autoFocus: false,
|
||||
};
|
||||
export const DEFAULT_DIALOG_CONFIG: DialogConfig = {
|
||||
small: { ...baseConfig, width: '360px' },
|
||||
medium: { ...baseConfig, width: '552px' },
|
||||
large: { ...baseConfig, width: '648px' },
|
||||
};
|
@ -1,4 +1,4 @@
|
||||
<h2 class="mat-headline">{{ data.title ? data.title : 'Confirm this action' }}</h2>
|
||||
<h2 class="mat-headline">{{ title }}</h2>
|
||||
<div
|
||||
mat-dialog-actions
|
||||
class="dialog-actions"
|
||||
|
@ -9,10 +9,13 @@ import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
|
||||
export class ConfirmActionDialogComponent {
|
||||
constructor(
|
||||
public dialogRef: MatDialogRef<ConfirmActionDialogComponent, 'cancel' | 'confirm'>,
|
||||
@Inject(MAT_DIALOG_DATA)
|
||||
public data: { title?: string }
|
||||
@Inject(MAT_DIALOG_DATA) public data: { title?: string }
|
||||
) {}
|
||||
|
||||
get title() {
|
||||
return this.data?.title ?? 'Confirm this action';
|
||||
}
|
||||
|
||||
cancel() {
|
||||
this.dialogRef.close('cancel');
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user