mirror of
https://github.com/valitydev/control-center.git
synced 2024-11-06 02:25:17 +00:00
IMP-82: Terminals page (#275)
This commit is contained in:
parent
bf8c021c9d
commit
4d171ef8ea
@ -1,10 +1,24 @@
|
|||||||
|
LICENSE
|
||||||
|
|
||||||
|
.idea
|
||||||
|
.vscode
|
||||||
|
|
||||||
package.json
|
package.json
|
||||||
package-lock.json
|
package-lock.json
|
||||||
node_modules
|
node_modules
|
||||||
dist
|
.npmrc
|
||||||
src/assets/icons/
|
|
||||||
.angular
|
.angular
|
||||||
LICENSE
|
.run
|
||||||
|
dist
|
||||||
|
|
||||||
Dockerfile
|
Dockerfile
|
||||||
*.conf
|
*.conf
|
||||||
|
|
||||||
|
.*ignore
|
||||||
*.env
|
*.env
|
||||||
|
|
||||||
|
*.ico
|
||||||
|
*.ttf
|
||||||
|
|
||||||
|
src/assets/icons/
|
||||||
|
@ -1 +1 @@
|
|||||||
module.exports = require("@vality/prettier-config");
|
module.exports = require('@vality/prettier-config');
|
||||||
|
41
package-lock.json
generated
41
package-lock.json
generated
@ -29,7 +29,7 @@
|
|||||||
"@vality/dominant-cache-proto": "2.0.0",
|
"@vality/dominant-cache-proto": "2.0.0",
|
||||||
"@vality/fistful-proto": "2.0.1-ed97a0e.0",
|
"@vality/fistful-proto": "2.0.1-ed97a0e.0",
|
||||||
"@vality/magista-proto": "2.0.2-37b81e6.0",
|
"@vality/magista-proto": "2.0.2-37b81e6.0",
|
||||||
"@vality/ng-core": "16.2.1-pr-40-bdc62db.0",
|
"@vality/ng-core": "16.2.1-pr-40-c4e5174.0",
|
||||||
"@vality/payout-manager-proto": "2.0.0",
|
"@vality/payout-manager-proto": "2.0.0",
|
||||||
"@vality/repairer-proto": "2.0.2-f5e3b7a.0",
|
"@vality/repairer-proto": "2.0.2-f5e3b7a.0",
|
||||||
"@vality/thrift-ts": "2.4.1-8ad5123.0",
|
"@vality/thrift-ts": "2.4.1-8ad5123.0",
|
||||||
@ -37,6 +37,7 @@
|
|||||||
"coerce-property": "15.0.1",
|
"coerce-property": "15.0.1",
|
||||||
"css-element-queries": "1.2.3",
|
"css-element-queries": "1.2.3",
|
||||||
"date-fns": "2.30.0",
|
"date-fns": "2.30.0",
|
||||||
|
"fuse.js": "6.6.2",
|
||||||
"humanize-duration": "3.21.0",
|
"humanize-duration": "3.21.0",
|
||||||
"inputmask": "5.0.7",
|
"inputmask": "5.0.7",
|
||||||
"keycloak-angular": "14.0.0",
|
"keycloak-angular": "14.0.0",
|
||||||
@ -66,8 +67,8 @@
|
|||||||
"@types/lodash-es": "4.17.6",
|
"@types/lodash-es": "4.17.6",
|
||||||
"@types/papaparse": "5.3.7",
|
"@types/papaparse": "5.3.7",
|
||||||
"@vality/cspell-config": "7.0.1-pr-33-8e9a771.0",
|
"@vality/cspell-config": "7.0.1-pr-33-8e9a771.0",
|
||||||
"@vality/eslint-config": "8.0.1-pr-33-541079b.0",
|
"@vality/eslint-config": "8.1.1-pr-40-c4e5174.0",
|
||||||
"@vality/prettier-config": "3.0.1-pr-33-1086ab7.0",
|
"@vality/prettier-config": "3.0.1-pr-40-c4e5174.0",
|
||||||
"cross-env": "7.0.3",
|
"cross-env": "7.0.3",
|
||||||
"cspell": "^7.0.0",
|
"cspell": "^7.0.0",
|
||||||
"eslint": "^8.39.0",
|
"eslint": "^8.39.0",
|
||||||
@ -79,7 +80,7 @@
|
|||||||
"karma-coverage-istanbul-reporter": "3.0.3",
|
"karma-coverage-istanbul-reporter": "3.0.3",
|
||||||
"karma-jasmine": "5.1.0",
|
"karma-jasmine": "5.1.0",
|
||||||
"karma-jasmine-html-reporter": "2.0.0",
|
"karma-jasmine-html-reporter": "2.0.0",
|
||||||
"prettier": "3.0.1",
|
"prettier": "3.0.3",
|
||||||
"typescript": "~5.0.4",
|
"typescript": "~5.0.4",
|
||||||
"typescript-memoize": "1.1.1"
|
"typescript-memoize": "1.1.1"
|
||||||
}
|
}
|
||||||
@ -5783,9 +5784,9 @@
|
|||||||
"integrity": "sha512-Jxo7n8/2xo8D/y7g0v1iFjr5MijOYmJ0hiHNTqoj/D0elzRhHAeRBur9F8h4RDf6sd2/+FmtVlprc7+q0/AGig=="
|
"integrity": "sha512-Jxo7n8/2xo8D/y7g0v1iFjr5MijOYmJ0hiHNTqoj/D0elzRhHAeRBur9F8h4RDf6sd2/+FmtVlprc7+q0/AGig=="
|
||||||
},
|
},
|
||||||
"node_modules/@vality/eslint-config": {
|
"node_modules/@vality/eslint-config": {
|
||||||
"version": "8.0.1-pr-33-541079b.0",
|
"version": "8.1.1-pr-40-c4e5174.0",
|
||||||
"resolved": "https://registry.npmjs.org/@vality/eslint-config/-/eslint-config-8.0.1-pr-33-541079b.0.tgz",
|
"resolved": "https://registry.npmjs.org/@vality/eslint-config/-/eslint-config-8.1.1-pr-40-c4e5174.0.tgz",
|
||||||
"integrity": "sha512-FvkI4bhsfWjJYmpw0lFPqajxlA4cNNDvoIRaelkJcr70iEq1xIol+vYHqvqV8jEc8z0W3xrApseSFOxjTMzMnw==",
|
"integrity": "sha512-nKOHesoVfatRqdmZUk7S6qm3zs41BxDQam768QAiS81k6rQ52sQwdOZgJYFGm36r2fvokb1KxEnSrIRfqY8U+g==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@angular-eslint/eslint-plugin": "^16.1.0",
|
"@angular-eslint/eslint-plugin": "^16.1.0",
|
||||||
@ -6000,9 +6001,9 @@
|
|||||||
"integrity": "sha512-gJizpTWuB74L+XuJ+dUaxAwJDkycdnuVwrXWIl/NKcS7++/zgrgTpw+tM5/Te3rWqkkCnSxC1SK0C4aPbbtifg=="
|
"integrity": "sha512-gJizpTWuB74L+XuJ+dUaxAwJDkycdnuVwrXWIl/NKcS7++/zgrgTpw+tM5/Te3rWqkkCnSxC1SK0C4aPbbtifg=="
|
||||||
},
|
},
|
||||||
"node_modules/@vality/ng-core": {
|
"node_modules/@vality/ng-core": {
|
||||||
"version": "16.2.1-pr-40-bdc62db.0",
|
"version": "16.2.1-pr-40-c4e5174.0",
|
||||||
"resolved": "https://registry.npmjs.org/@vality/ng-core/-/ng-core-16.2.1-pr-40-bdc62db.0.tgz",
|
"resolved": "https://registry.npmjs.org/@vality/ng-core/-/ng-core-16.2.1-pr-40-c4e5174.0.tgz",
|
||||||
"integrity": "sha512-hw7ljBUP1X1WYt6ZEQZ2E+y0Udy7G5pUNWL1wUIMmexaXr5H21NTuRZRgy9u3zfxrYfNnLmmI1XZgLfZry/gkA==",
|
"integrity": "sha512-gIJrzmrS+vxSdo+0F66imWNZdf7hC5tA74Le3glQSsbr9ZhmldYaBE5559a3VWCwF4VITrADCGBV3tt2nxjM/Q==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@ng-matero/extensions": "^16.0.0",
|
"@ng-matero/extensions": "^16.0.0",
|
||||||
"@s-libs/js-core": "^16.0.0",
|
"@s-libs/js-core": "^16.0.0",
|
||||||
@ -6032,9 +6033,9 @@
|
|||||||
"integrity": "sha512-eBR/QJQObjfRQPOSR29vafvvfYVaAvrKJGYVxGo7j4ZWWf9KWDlR4cipixNnZyZ/esLNX2fdqebWbfogrOBdSA=="
|
"integrity": "sha512-eBR/QJQObjfRQPOSR29vafvvfYVaAvrKJGYVxGo7j4ZWWf9KWDlR4cipixNnZyZ/esLNX2fdqebWbfogrOBdSA=="
|
||||||
},
|
},
|
||||||
"node_modules/@vality/prettier-config": {
|
"node_modules/@vality/prettier-config": {
|
||||||
"version": "3.0.1-pr-33-1086ab7.0",
|
"version": "3.0.1-pr-40-c4e5174.0",
|
||||||
"resolved": "https://registry.npmjs.org/@vality/prettier-config/-/prettier-config-3.0.1-pr-33-1086ab7.0.tgz",
|
"resolved": "https://registry.npmjs.org/@vality/prettier-config/-/prettier-config-3.0.1-pr-40-c4e5174.0.tgz",
|
||||||
"integrity": "sha512-TurfC2o3w8owbXTC9KTTZef0dlr4EX7l3pfcA8Ubht9lf4YmPiTs86sicMcwQaeyfTKWQExfnsSw99JG90DAAQ==",
|
"integrity": "sha512-1w5LgPbZxc4j3tam7RIA6NKLNabCI/BWsrx3gSiWVTZfEWSOl43e7UBLv+Mq+Bc/8gdvl1eNNRRjvGkJU82Brw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"prettier-plugin-organize-attributes": "^1.0.0"
|
"prettier-plugin-organize-attributes": "^1.0.0"
|
||||||
@ -13360,6 +13361,14 @@
|
|||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/fuse.js": {
|
||||||
|
"version": "6.6.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/fuse.js/-/fuse.js-6.6.2.tgz",
|
||||||
|
"integrity": "sha512-cJaJkxCCxC8qIIcPBF9yGxY0W/tVZS3uEISDxhYIdtk8OL93pe+6Zj7LjCqVV4dzbqcriOZ+kQ/NE4RXZHsIGA==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/gauge": {
|
"node_modules/gauge": {
|
||||||
"version": "4.0.4",
|
"version": "4.0.4",
|
||||||
"resolved": "https://registry.npmjs.org/gauge/-/gauge-4.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/gauge/-/gauge-4.0.4.tgz",
|
||||||
@ -18549,9 +18558,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/prettier": {
|
"node_modules/prettier": {
|
||||||
"version": "3.0.1",
|
"version": "3.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.0.3.tgz",
|
||||||
"integrity": "sha512-fcOWSnnpCrovBsmFZIGIy9UqK2FaI7Hqax+DIO0A9UxeVoY4iweyaFjS5TavZN97Hfehph0nhsZnjlVKzEQSrQ==",
|
"integrity": "sha512-L/4pUDMxcNa8R/EthV08Zt42WBO4h1rarVtK0K+QJG0X187OLo7l699jWw0GKuwzkPQ//jMFA/8Xm6Fh3J/DAg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"bin": {
|
"bin": {
|
||||||
"prettier": "bin/prettier.cjs"
|
"prettier": "bin/prettier.cjs"
|
||||||
|
13
package.json
13
package.json
@ -9,8 +9,8 @@
|
|||||||
"test": "ng test",
|
"test": "ng test",
|
||||||
"lint": "ng lint --max-warnings=0",
|
"lint": "ng lint --max-warnings=0",
|
||||||
"lint:fix": "ng lint --fix",
|
"lint:fix": "ng lint --fix",
|
||||||
"format": "prettier * --list-different",
|
"format": "prettier ** --list-different",
|
||||||
"format:fix": "prettier * --write --loglevel warn",
|
"format:fix": "prettier ** --write --log-level=warn",
|
||||||
"spell": "cspell --no-progress **",
|
"spell": "cspell --no-progress **",
|
||||||
"spell:fix": "cspell --no-progress --show-suggestions --show-context **",
|
"spell:fix": "cspell --no-progress --show-suggestions --show-context **",
|
||||||
"fix": "npm run lint:fix && npm run format:fix"
|
"fix": "npm run lint:fix && npm run format:fix"
|
||||||
@ -37,7 +37,7 @@
|
|||||||
"@vality/dominant-cache-proto": "2.0.0",
|
"@vality/dominant-cache-proto": "2.0.0",
|
||||||
"@vality/fistful-proto": "2.0.1-ed97a0e.0",
|
"@vality/fistful-proto": "2.0.1-ed97a0e.0",
|
||||||
"@vality/magista-proto": "2.0.2-37b81e6.0",
|
"@vality/magista-proto": "2.0.2-37b81e6.0",
|
||||||
"@vality/ng-core": "16.2.1-pr-40-bdc62db.0",
|
"@vality/ng-core": "16.2.1-pr-40-c4e5174.0",
|
||||||
"@vality/payout-manager-proto": "2.0.0",
|
"@vality/payout-manager-proto": "2.0.0",
|
||||||
"@vality/repairer-proto": "2.0.2-f5e3b7a.0",
|
"@vality/repairer-proto": "2.0.2-f5e3b7a.0",
|
||||||
"@vality/thrift-ts": "2.4.1-8ad5123.0",
|
"@vality/thrift-ts": "2.4.1-8ad5123.0",
|
||||||
@ -45,6 +45,7 @@
|
|||||||
"coerce-property": "15.0.1",
|
"coerce-property": "15.0.1",
|
||||||
"css-element-queries": "1.2.3",
|
"css-element-queries": "1.2.3",
|
||||||
"date-fns": "2.30.0",
|
"date-fns": "2.30.0",
|
||||||
|
"fuse.js": "6.6.2",
|
||||||
"humanize-duration": "3.21.0",
|
"humanize-duration": "3.21.0",
|
||||||
"inputmask": "5.0.7",
|
"inputmask": "5.0.7",
|
||||||
"keycloak-angular": "14.0.0",
|
"keycloak-angular": "14.0.0",
|
||||||
@ -74,8 +75,8 @@
|
|||||||
"@types/lodash-es": "4.17.6",
|
"@types/lodash-es": "4.17.6",
|
||||||
"@types/papaparse": "5.3.7",
|
"@types/papaparse": "5.3.7",
|
||||||
"@vality/cspell-config": "7.0.1-pr-33-8e9a771.0",
|
"@vality/cspell-config": "7.0.1-pr-33-8e9a771.0",
|
||||||
"@vality/eslint-config": "8.0.1-pr-33-541079b.0",
|
"@vality/eslint-config": "8.1.1-pr-40-c4e5174.0",
|
||||||
"@vality/prettier-config": "3.0.1-pr-33-1086ab7.0",
|
"@vality/prettier-config": "3.0.1-pr-40-c4e5174.0",
|
||||||
"cross-env": "7.0.3",
|
"cross-env": "7.0.3",
|
||||||
"cspell": "^7.0.0",
|
"cspell": "^7.0.0",
|
||||||
"eslint": "^8.39.0",
|
"eslint": "^8.39.0",
|
||||||
@ -87,7 +88,7 @@
|
|||||||
"karma-coverage-istanbul-reporter": "3.0.3",
|
"karma-coverage-istanbul-reporter": "3.0.3",
|
||||||
"karma-jasmine": "5.1.0",
|
"karma-jasmine": "5.1.0",
|
||||||
"karma-jasmine-html-reporter": "2.0.0",
|
"karma-jasmine-html-reporter": "2.0.0",
|
||||||
"prettier": "3.0.1",
|
"prettier": "3.0.3",
|
||||||
"typescript": "~5.0.4",
|
"typescript": "~5.0.4",
|
||||||
"typescript-memoize": "1.1.1"
|
"typescript-memoize": "1.1.1"
|
||||||
}
|
}
|
||||||
|
@ -1 +0,0 @@
|
|||||||
export * from './domain-store.service';
|
|
@ -1 +1,2 @@
|
|||||||
export * from './repository.service';
|
export * from './repository.service';
|
||||||
|
export * from './stores/domain-store.service';
|
||||||
|
@ -5,12 +5,11 @@ import { Commit, Snapshot, Version } from '@vality/domain-proto/domain_config';
|
|||||||
import { BehaviorSubject, defer, Observable, of, ReplaySubject } from 'rxjs';
|
import { BehaviorSubject, defer, Observable, of, ReplaySubject } from 'rxjs';
|
||||||
import { map, pluck, shareReplay, startWith, switchMap, take, tap } from 'rxjs/operators';
|
import { map, pluck, shareReplay, startWith, switchMap, take, tap } from 'rxjs/operators';
|
||||||
|
|
||||||
import { RepositoryService } from '@cc/app/api/domain-config';
|
import { inProgressFrom, progressTo } from '../../../../utils';
|
||||||
import { DomainSecretService } from '@cc/app/shared/services/domain-secret-service';
|
import { getUnionKey } from '../../../../utils/get-union-key';
|
||||||
import { inProgressFrom, progressTo } from '@cc/utils';
|
import { DomainSecretService } from '../../../shared/services/domain-secret-service';
|
||||||
import { getUnionKey } from '@cc/utils/get-union-key';
|
import { handleError, NotificationErrorService } from '../../../shared/services/notification-error';
|
||||||
|
import { RepositoryService } from '../index';
|
||||||
import { handleError, NotificationErrorService } from '../../shared/services/notification-error';
|
|
||||||
|
|
||||||
@UntilDestroy()
|
@UntilDestroy()
|
||||||
@Injectable({
|
@Injectable({
|
||||||
@ -68,7 +67,9 @@ export class DomainStoreService {
|
|||||||
return version$.pipe(
|
return version$.pipe(
|
||||||
switchMap((v) => this.repositoryService.Commit(v, commit)),
|
switchMap((v) => this.repositoryService.Commit(v, commit)),
|
||||||
tap(() => {
|
tap(() => {
|
||||||
if (reload) this.forceReload();
|
if (reload) {
|
||||||
|
this.forceReload();
|
||||||
|
}
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
}
|
}
|
@ -1,5 +1,4 @@
|
|||||||
<mat-toolbar class="toolbar" color="primary">
|
<mat-toolbar class="toolbar" color="primary">
|
||||||
<button mat-icon-button (click)="sidenav.toggle()"><mat-icon>menu</mat-icon></button>
|
|
||||||
<span>Control Center</span> <span class="spacer"></span> <span>{{ username }}</span>
|
<span>Control Center</span> <span class="spacer"></span> <span>{{ username }}</span>
|
||||||
<button [matMenuTriggerFor]="userMenu" mat-icon-button><mat-icon>more_vert</mat-icon></button>
|
<button [matMenuTriggerFor]="userMenu" mat-icon-button><mat-icon>more_vert</mat-icon></button>
|
||||||
</mat-toolbar>
|
</mat-toolbar>
|
||||||
@ -7,14 +6,7 @@
|
|||||||
<mat-menu #userMenu="matMenu"> <button mat-menu-item (click)="logout()">Logout</button> </mat-menu>
|
<mat-menu #userMenu="matMenu"> <button mat-menu-item (click)="logout()">Logout</button> </mat-menu>
|
||||||
|
|
||||||
<mat-sidenav-container autosize class="container">
|
<mat-sidenav-container autosize class="container">
|
||||||
<mat-sidenav
|
<mat-sidenav fixedInViewport="true" fixedTopGap="64" mode="side" opened role="navigation">
|
||||||
#sidenav
|
|
||||||
[(opened)]="opened"
|
|
||||||
fixedInViewport="true"
|
|
||||||
fixedTopGap="64"
|
|
||||||
mode="side"
|
|
||||||
role="navigation"
|
|
||||||
>
|
|
||||||
<mat-nav-list>
|
<mat-nav-list>
|
||||||
<ng-container *ngFor="let group of menuItems; let i = index">
|
<ng-container *ngFor="let group of menuItems; let i = index">
|
||||||
<mat-divider *ngIf="i !== 0"></mat-divider>
|
<mat-divider *ngIf="i !== 0"></mat-divider>
|
||||||
|
@ -12,11 +12,10 @@ import { ROUTING_CONFIG as PAYOUTS_ROUTING_CONFIG } from './sections/payouts/pay
|
|||||||
import { ROUTING_CONFIG as REPAIRING_ROUTING_CONFIG } from './sections/repairing/routing-config';
|
import { ROUTING_CONFIG as REPAIRING_ROUTING_CONFIG } from './sections/repairing/routing-config';
|
||||||
import { ROUTING_CONFIG as PARTIES_ROUTING_CONFIG } from './sections/search-parties/routing-config';
|
import { ROUTING_CONFIG as PARTIES_ROUTING_CONFIG } from './sections/search-parties/routing-config';
|
||||||
import { ROUTING_CONFIG as SOURCES_ROUTING_CONFIG } from './sections/sources/routing-config';
|
import { ROUTING_CONFIG as SOURCES_ROUTING_CONFIG } from './sections/sources/routing-config';
|
||||||
|
import { ROUTING_CONFIG as TERMINALS_ROUTING_CONFIG } from './sections/terminals';
|
||||||
import { ROUTING_CONFIG as WALLETS_ROUTING_CONFIG } from './sections/wallets/routing-config';
|
import { ROUTING_CONFIG as WALLETS_ROUTING_CONFIG } from './sections/wallets/routing-config';
|
||||||
import { ROUTING_CONFIG as WITHDRAWALS_ROUTING_CONFIG } from './sections/withdrawals/routing-config';
|
import { ROUTING_CONFIG as WITHDRAWALS_ROUTING_CONFIG } from './sections/withdrawals/routing-config';
|
||||||
import { SidenavInfoService } from './shared/components/sidenav-info/sidenav-info.service';
|
import { SidenavInfoService } from './shared/components/sidenav-info';
|
||||||
|
|
||||||
const SIDENAV_OPENED_KEY = 'sidenav-opened';
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'cc-root',
|
selector: 'cc-root',
|
||||||
@ -27,13 +26,6 @@ export class AppComponent implements OnInit {
|
|||||||
username: string;
|
username: string;
|
||||||
menuItems: { name: string; route: string }[][] = [];
|
menuItems: { name: string; route: string }[][] = [];
|
||||||
|
|
||||||
get opened(): boolean {
|
|
||||||
return localStorage.getItem(SIDENAV_OPENED_KEY) === String(true);
|
|
||||||
}
|
|
||||||
set opened(opened: boolean) {
|
|
||||||
localStorage.setItem(SIDENAV_OPENED_KEY, String(opened));
|
|
||||||
}
|
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private keycloakService: KeycloakService,
|
private keycloakService: KeycloakService,
|
||||||
private appAuthGuardService: AppAuthGuardService,
|
private appAuthGuardService: AppAuthGuardService,
|
||||||
@ -59,6 +51,11 @@ export class AppComponent implements OnInit {
|
|||||||
route: '/domain',
|
route: '/domain',
|
||||||
services: DOMAIN_ROUTING_CONFIG.services,
|
services: DOMAIN_ROUTING_CONFIG.services,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: 'Terminals',
|
||||||
|
route: '/terminals',
|
||||||
|
services: TERMINALS_ROUTING_CONFIG.services,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: 'Repairing',
|
name: 'Repairing',
|
||||||
route: '/repairing',
|
route: '/repairing',
|
||||||
|
@ -108,13 +108,19 @@ export class CreateChargebacksByFileDialogComponent
|
|||||||
parseCsv(content, { header: this.hasHeaderControl.value || false, delimiter: ';' }),
|
parseCsv(content, { header: this.hasHeaderControl.value || false, delimiter: ';' }),
|
||||||
),
|
),
|
||||||
tap((d) => {
|
tap((d) => {
|
||||||
if (!d.errors.length) return;
|
if (!d.errors.length) {
|
||||||
if (d.errors.length === 1) this.log.error(d.errors[0]);
|
return;
|
||||||
|
}
|
||||||
|
if (d.errors.length === 1) {
|
||||||
|
this.log.error(d.errors[0]);
|
||||||
|
}
|
||||||
this.log.error(new Error(d.errors.map((e) => e.message).join('. ')));
|
this.log.error(new Error(d.errors.map((e) => e.message).join('. ')));
|
||||||
}),
|
}),
|
||||||
map((d) => {
|
map((d) => {
|
||||||
const chargebacks = unifyCsvItems(d?.data, CSV_CHARGEBACK_PROPS);
|
const chargebacks = unifyCsvItems(d?.data, CSV_CHARGEBACK_PROPS);
|
||||||
if (chargebacks[0].invoice_id) return chargebacks;
|
if (chargebacks[0].invoice_id) {
|
||||||
|
return chargebacks;
|
||||||
|
}
|
||||||
this.log.error(
|
this.log.error(
|
||||||
'Perhaps you incorrectly checked the checkbox to have or not a header (the first element does not have at least an invoice ID)',
|
'Perhaps you incorrectly checked the checkbox to have or not a header (the first element does not have at least an invoice ID)',
|
||||||
);
|
);
|
||||||
|
@ -84,7 +84,9 @@ export class ClaimComponent {
|
|||||||
untilDestroyed(this),
|
untilDestroyed(this),
|
||||||
)
|
)
|
||||||
.subscribe((result) => {
|
.subscribe((result) => {
|
||||||
if (result.status === DialogResponseStatus.Success) this.reloadClaim();
|
if (result.status === DialogResponseStatus.Success) {
|
||||||
|
this.reloadClaim();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -100,7 +102,9 @@ export class ClaimComponent {
|
|||||||
untilDestroyed(this),
|
untilDestroyed(this),
|
||||||
)
|
)
|
||||||
.subscribe((result) => {
|
.subscribe((result) => {
|
||||||
if (result.status === DialogResponseStatus.Success) this.reloadClaim();
|
if (result.status === DialogResponseStatus.Success) {
|
||||||
|
this.reloadClaim();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -76,7 +76,9 @@ export class ModificationUnitTimelineItemComponent {
|
|||||||
untilDestroyed(this),
|
untilDestroyed(this),
|
||||||
)
|
)
|
||||||
.subscribe((result) => {
|
.subscribe((result) => {
|
||||||
if (result.status === DialogResponseStatus.Success) this.claimChanged.emit();
|
if (result.status === DialogResponseStatus.Success) {
|
||||||
|
this.claimChanged.emit();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,8 +28,9 @@ export class AllowedClaimStatusesService {
|
|||||||
if (
|
if (
|
||||||
excludedStatuses.includes(status) ||
|
excludedStatuses.includes(status) ||
|
||||||
!includedCurrentStatuses.includes(currentClaimStatus)
|
!includedCurrentStatuses.includes(currentClaimStatus)
|
||||||
)
|
) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
return this.appAuthGuardService.userHasRoles(CLAIM_STATUS_ROLES[status]);
|
return this.appAuthGuardService.userHasRoles(CLAIM_STATUS_ROLES[status]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,7 @@ import startCase from 'lodash-es/startCase';
|
|||||||
import { combineLatest, Observable, ReplaySubject, defer } from 'rxjs';
|
import { combineLatest, Observable, ReplaySubject, defer } from 'rxjs';
|
||||||
import { map, switchMap, startWith, shareReplay, withLatestFrom, filter } from 'rxjs/operators';
|
import { map, switchMap, startWith, shareReplay, withLatestFrom, filter } from 'rxjs/operators';
|
||||||
|
|
||||||
import { DomainStoreService } from '@cc/app/api/deprecated-damsel';
|
import { DomainStoreService } from '@cc/app/api/domain-config';
|
||||||
import { objectToJSON } from '@cc/utils/thrift-instance';
|
import { objectToJSON } from '@cc/utils/thrift-instance';
|
||||||
|
|
||||||
import { Columns } from '../../../../../components/table';
|
import { Columns } from '../../../../../components/table';
|
||||||
|
@ -26,6 +26,8 @@ export function sortData(data: DataSourceItem[], sort: MatSort): DataSourceItem[
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (sort.direction === 'desc') return data.reverse();
|
if (sort.direction === 'desc') {
|
||||||
|
return data.reverse();
|
||||||
|
}
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,7 @@ import {
|
|||||||
import { from } from 'rxjs';
|
import { from } from 'rxjs';
|
||||||
import { filter, switchMap } from 'rxjs/operators';
|
import { filter, switchMap } from 'rxjs/operators';
|
||||||
|
|
||||||
import { DomainStoreService } from '@cc/app/api/deprecated-damsel';
|
import { DomainStoreService } from '@cc/app/api/domain-config';
|
||||||
import { DomainMetadataViewExtensionsService } from '@cc/app/shared/components/thrift-api-crud/domain/domain-thrift-viewer/services/domain-metadata-view-extensions';
|
import { DomainMetadataViewExtensionsService } from '@cc/app/shared/components/thrift-api-crud/domain/domain-thrift-viewer/services/domain-metadata-view-extensions';
|
||||||
|
|
||||||
import { enumHasValue } from '../../../../utils';
|
import { enumHasValue } from '../../../../utils';
|
||||||
|
@ -5,7 +5,7 @@ import { DomainObject } from '@vality/domain-proto/domain';
|
|||||||
import { BehaviorSubject } from 'rxjs';
|
import { BehaviorSubject } from 'rxjs';
|
||||||
import { withLatestFrom } from 'rxjs/operators';
|
import { withLatestFrom } from 'rxjs/operators';
|
||||||
|
|
||||||
import { DomainStoreService } from '@cc/app/api/deprecated-damsel';
|
import { DomainStoreService } from '@cc/app/api/domain-config';
|
||||||
import { DomainMetadataViewExtensionsService } from '@cc/app/shared/components/thrift-api-crud/domain/domain-thrift-viewer/services/domain-metadata-view-extensions';
|
import { DomainMetadataViewExtensionsService } from '@cc/app/shared/components/thrift-api-crud/domain/domain-thrift-viewer/services/domain-metadata-view-extensions';
|
||||||
|
|
||||||
import { progressTo, getUnionKey, enumHasValue } from '../../../../utils';
|
import { progressTo, getUnionKey, enumHasValue } from '../../../../utils';
|
||||||
|
@ -62,9 +62,11 @@ export class DomainObjModificationComponent implements OnInit {
|
|||||||
if (
|
if (
|
||||||
this.modifiedDomainObjectService.domainObject &&
|
this.modifiedDomainObjectService.domainObject &&
|
||||||
this.route.snapshot.params.ref === this.modifiedDomainObjectService.ref
|
this.route.snapshot.params.ref === this.modifiedDomainObjectService.ref
|
||||||
)
|
) {
|
||||||
this.control.setValue(this.modifiedDomainObjectService.domainObject);
|
this.control.setValue(this.modifiedDomainObjectService.domainObject);
|
||||||
else this.control.setValue(object);
|
} else {
|
||||||
|
this.control.setValue(object);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@ import { untilDestroyed, UntilDestroy } from '@ngneat/until-destroy';
|
|||||||
import { switchMap } from 'rxjs';
|
import { switchMap } from 'rxjs';
|
||||||
import { first, withLatestFrom } from 'rxjs/operators';
|
import { first, withLatestFrom } from 'rxjs/operators';
|
||||||
|
|
||||||
import { DomainStoreService } from '@cc/app/api/deprecated-damsel';
|
import { DomainStoreService } from '@cc/app/api/domain-config';
|
||||||
import { DomainSecretService } from '@cc/app/shared/services/domain-secret-service';
|
import { DomainSecretService } from '@cc/app/shared/services/domain-secret-service';
|
||||||
import { NotificationErrorService } from '@cc/app/shared/services/notification-error';
|
import { NotificationErrorService } from '@cc/app/shared/services/notification-error';
|
||||||
|
|
||||||
|
@ -4,10 +4,11 @@ import { DomainObject, Reference } from '@vality/domain-proto/domain';
|
|||||||
import { Observable, switchMap, BehaviorSubject, defer } from 'rxjs';
|
import { Observable, switchMap, BehaviorSubject, defer } from 'rxjs';
|
||||||
import { map, shareReplay, first } from 'rxjs/operators';
|
import { map, shareReplay, first } from 'rxjs/operators';
|
||||||
|
|
||||||
import { DomainStoreService } from '@cc/app/api/deprecated-damsel/domain-store.service';
|
|
||||||
import { NotificationErrorService } from '@cc/app/shared/services/notification-error';
|
import { NotificationErrorService } from '@cc/app/shared/services/notification-error';
|
||||||
import { toJson, getUnionValue, progressTo } from '@cc/utils';
|
import { toJson, getUnionValue, progressTo } from '@cc/utils';
|
||||||
|
|
||||||
|
import { DomainStoreService } from '../../../api/domain-config/stores/domain-store.service';
|
||||||
|
|
||||||
import { MetadataService } from './metadata.service';
|
import { MetadataService } from './metadata.service';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
|
@ -10,7 +10,15 @@
|
|||||||
></v-input-field>
|
></v-input-field>
|
||||||
</mat-card-content>
|
</mat-card-content>
|
||||||
</mat-card>
|
</mat-card>
|
||||||
<v-table [columns]="columns" [data]="shops$ | async" noActions></v-table>
|
<v-table
|
||||||
|
[columns]="columns"
|
||||||
|
[data]="shops$ | async"
|
||||||
|
[progress]="shopsProgress$ | async"
|
||||||
|
[size]="100"
|
||||||
|
noActions
|
||||||
|
sortActive="details.name"
|
||||||
|
sortOnFront
|
||||||
|
></v-table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -40,7 +40,11 @@ export class PartyShopsComponent {
|
|||||||
),
|
),
|
||||||
]).pipe(
|
]).pipe(
|
||||||
map(([shops, searchStr]) =>
|
map(([shops, searchStr]) =>
|
||||||
shops.filter((s) => JSON.stringify(s).toLowerCase().includes(searchStr.toLowerCase())),
|
searchStr
|
||||||
|
? shops.filter((s) =>
|
||||||
|
JSON.stringify(s).toLowerCase().includes(searchStr.toLowerCase()),
|
||||||
|
)
|
||||||
|
: shops,
|
||||||
),
|
),
|
||||||
shareReplay({ refCount: true, bufferSize: 1 }),
|
shareReplay({ refCount: true, bufferSize: 1 }),
|
||||||
);
|
);
|
||||||
@ -54,6 +58,7 @@ export class PartyShopsComponent {
|
|||||||
this.selectedShop = d;
|
this.selectedShop = d;
|
||||||
this.sidenavInfoService.toggle(this.shopTpl, d.details.name || `Shop #${d.id}`, d);
|
this.sidenavInfoService.toggle(this.shopTpl, d.details.name || `Shop #${d.id}`, d);
|
||||||
},
|
},
|
||||||
|
sortable: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
field: 'contract_id',
|
field: 'contract_id',
|
||||||
@ -114,6 +119,7 @@ export class PartyShopsComponent {
|
|||||||
]),
|
]),
|
||||||
];
|
];
|
||||||
progress$ = new BehaviorSubject(0);
|
progress$ = new BehaviorSubject(0);
|
||||||
|
shopsProgress$ = this.partyShopsService.progress$;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private partyShopsService: PartyShopsService,
|
private partyShopsService: PartyShopsService,
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import { ActivatedRoute } from '@angular/router';
|
import { ActivatedRoute } from '@angular/router';
|
||||||
import { Party } from '@vality/domain-proto/domain';
|
import { Party } from '@vality/domain-proto/domain';
|
||||||
import { defer, merge, Observable, Subject } from 'rxjs';
|
import { progressTo } from '@vality/ng-core';
|
||||||
|
import { defer, merge, Observable, Subject, BehaviorSubject } from 'rxjs';
|
||||||
import { map, shareReplay, switchMap } from 'rxjs/operators';
|
import { map, shareReplay, switchMap } from 'rxjs/operators';
|
||||||
|
|
||||||
import { PartyManagementService } from '@cc/app/api/payment-processing';
|
import { PartyManagementService } from '@cc/app/api/payment-processing';
|
||||||
@ -12,6 +13,7 @@ export class PartyShopsService {
|
|||||||
map((p) => p.shops),
|
map((p) => p.shops),
|
||||||
map((shops) => Array.from(shops.values())),
|
map((shops) => Array.from(shops.values())),
|
||||||
);
|
);
|
||||||
|
progress$ = new BehaviorSubject(0);
|
||||||
|
|
||||||
private reload$ = new Subject<void>();
|
private reload$ = new Subject<void>();
|
||||||
|
|
||||||
@ -20,7 +22,9 @@ export class PartyShopsService {
|
|||||||
this.reload$.pipe(map(() => this.route.snapshot.params)),
|
this.reload$.pipe(map(() => this.route.snapshot.params)),
|
||||||
).pipe(
|
).pipe(
|
||||||
map((p) => p.partyID),
|
map((p) => p.partyID),
|
||||||
switchMap((partyID) => this.partyManagementService.Get(partyID)),
|
switchMap((partyID) =>
|
||||||
|
this.partyManagementService.Get(partyID).pipe(progressTo(this.progress$)),
|
||||||
|
),
|
||||||
shareReplay(1),
|
shareReplay(1),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -56,7 +56,9 @@ export class PaymentDetailsComponent {
|
|||||||
.afterClosed()
|
.afterClosed()
|
||||||
.pipe(untilDestroyed(this))
|
.pipe(untilDestroyed(this))
|
||||||
.subscribe(({ status }) => {
|
.subscribe(({ status }) => {
|
||||||
if (status === DialogResponseStatus.Success) this.updateChargebacks$.next();
|
if (status === DialogResponseStatus.Success) {
|
||||||
|
this.updateChargebacks$.next();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@ import { Injectable } from '@angular/core';
|
|||||||
import { merge, of, Subject } from 'rxjs';
|
import { merge, of, Subject } from 'rxjs';
|
||||||
import { catchError, filter, map, shareReplay, startWith, switchMap } from 'rxjs/operators';
|
import { catchError, filter, map, shareReplay, startWith, switchMap } from 'rxjs/operators';
|
||||||
|
|
||||||
import { DomainStoreService } from '@cc/app/api/deprecated-damsel';
|
import { DomainStoreService } from '@cc/app/api/domain-config';
|
||||||
import { progress } from '@cc/app/shared/custom-operators';
|
import { progress } from '@cc/app/shared/custom-operators';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
|
@ -2,7 +2,7 @@ import { Injectable } from '@angular/core';
|
|||||||
import { merge, of, Subject } from 'rxjs';
|
import { merge, of, Subject } from 'rxjs';
|
||||||
import { catchError, filter, map, shareReplay, startWith, switchMap } from 'rxjs/operators';
|
import { catchError, filter, map, shareReplay, startWith, switchMap } from 'rxjs/operators';
|
||||||
|
|
||||||
import { DomainStoreService } from '@cc/app/api/deprecated-damsel';
|
import { DomainStoreService } from '@cc/app/api/domain-config';
|
||||||
import { progress } from '@cc/app/shared/custom-operators';
|
import { progress } from '@cc/app/shared/custom-operators';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
|
@ -75,7 +75,9 @@ export class CreatePaymentAdjustmentComponent extends DialogSuperclass<
|
|||||||
.map((w) => {
|
.map((w) => {
|
||||||
const error: string =
|
const error: string =
|
||||||
w.error?.['name'] || w.error?.['message'] || '';
|
w.error?.['name'] || w.error?.['message'] || '';
|
||||||
if (error) return `${w.payment.id}: ${error}`;
|
if (error) {
|
||||||
|
return `${w.payment.id}: ${error}`;
|
||||||
|
}
|
||||||
return null;
|
return null;
|
||||||
})
|
})
|
||||||
.filter(Boolean)
|
.filter(Boolean)
|
||||||
|
@ -18,7 +18,7 @@ import { Moment } from 'moment';
|
|||||||
import { BehaviorSubject } from 'rxjs';
|
import { BehaviorSubject } from 'rxjs';
|
||||||
import { filter, map, switchMap, shareReplay } from 'rxjs/operators';
|
import { filter, map, switchMap, shareReplay } from 'rxjs/operators';
|
||||||
|
|
||||||
import { DomainStoreService } from '@cc/app/api/deprecated-damsel';
|
import { DomainStoreService } from '@cc/app/api/domain-config';
|
||||||
import { NotificationErrorService } from '@cc/app/shared/services/notification-error';
|
import { NotificationErrorService } from '@cc/app/shared/services/notification-error';
|
||||||
import { getEnumKey } from '@cc/utils';
|
import { getEnumKey } from '@cc/utils';
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@ import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy';
|
|||||||
import { DialogService } from '@vality/ng-core';
|
import { DialogService } from '@vality/ng-core';
|
||||||
import { first, map } from 'rxjs/operators';
|
import { first, map } from 'rxjs/operators';
|
||||||
|
|
||||||
import { DomainStoreService } from '@cc/app/api/deprecated-damsel';
|
import { DomainStoreService } from '@cc/app/api/domain-config';
|
||||||
import { RoutingRulesType } from '@cc/app/sections/routing-rules/types/routing-rules-type';
|
import { RoutingRulesType } from '@cc/app/sections/routing-rules/types/routing-rules-type';
|
||||||
import { NotificationErrorService } from '@cc/app/shared/services/notification-error';
|
import { NotificationErrorService } from '@cc/app/shared/services/notification-error';
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@ import {
|
|||||||
import { combineLatest, Observable } from 'rxjs';
|
import { combineLatest, Observable } from 'rxjs';
|
||||||
import { map, pluck, startWith, switchMap } from 'rxjs/operators';
|
import { map, pluck, startWith, switchMap } from 'rxjs/operators';
|
||||||
|
|
||||||
import { DomainStoreService } from '@cc/app/api/deprecated-damsel';
|
import { DomainStoreService } from '@cc/app/api/domain-config';
|
||||||
|
|
||||||
import { RoutingRulesService } from '../services/routing-rules';
|
import { RoutingRulesService } from '../services/routing-rules';
|
||||||
import { RoutingRulesType } from '../types/routing-rules-type';
|
import { RoutingRulesType } from '../types/routing-rules-type';
|
||||||
|
@ -5,7 +5,7 @@ import { DialogService, DialogResponseStatus } from '@vality/ng-core';
|
|||||||
import { combineLatest, Observable } from 'rxjs';
|
import { combineLatest, Observable } from 'rxjs';
|
||||||
import { filter, map, pluck, shareReplay, startWith, switchMap, take } from 'rxjs/operators';
|
import { filter, map, pluck, shareReplay, startWith, switchMap, take } from 'rxjs/operators';
|
||||||
|
|
||||||
import { DomainStoreService } from '@cc/app/api/deprecated-damsel';
|
import { DomainStoreService } from '@cc/app/api/domain-config';
|
||||||
|
|
||||||
import { RoutingRulesType } from '../types/routing-rules-type';
|
import { RoutingRulesType } from '../types/routing-rules-type';
|
||||||
|
|
||||||
|
@ -19,11 +19,9 @@
|
|||||||
[columns]="columns"
|
[columns]="columns"
|
||||||
[data]="(candidates$ | async) || []"
|
[data]="(candidates$ | async) || []"
|
||||||
[progress]="isLoading$ | async"
|
[progress]="isLoading$ | async"
|
||||||
[sortActive]="sort.active"
|
[sort]="{ active: 'priority', direction: 'desc' }"
|
||||||
[sortDirection]="sort.direction"
|
|
||||||
noActions
|
noActions
|
||||||
sortOnFront
|
sortOnFront
|
||||||
(sortChange)="sort = $event"
|
|
||||||
></v-table>
|
></v-table>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
import { Component, ViewChild, TemplateRef } from '@angular/core';
|
import { Component, ViewChild, TemplateRef } from '@angular/core';
|
||||||
import { Sort } from '@angular/material/sort';
|
|
||||||
import { ActivatedRoute } from '@angular/router';
|
import { ActivatedRoute } from '@angular/router';
|
||||||
import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy';
|
import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy';
|
||||||
import { TerminalObject, RoutingCandidate, Predicate } from '@vality/domain-proto/domain';
|
import { TerminalObject, RoutingCandidate, Predicate } from '@vality/domain-proto/domain';
|
||||||
@ -13,7 +12,7 @@ import {
|
|||||||
import { Observable, combineLatest } from 'rxjs';
|
import { Observable, combineLatest } from 'rxjs';
|
||||||
import { first, map, switchMap, withLatestFrom } from 'rxjs/operators';
|
import { first, map, switchMap, withLatestFrom } from 'rxjs/operators';
|
||||||
|
|
||||||
import { DomainStoreService } from '@cc/app/api/deprecated-damsel';
|
import { DomainStoreService } from '@cc/app/api/domain-config';
|
||||||
import { RoutingRulesType } from '@cc/app/sections/routing-rules/types/routing-rules-type';
|
import { RoutingRulesType } from '@cc/app/sections/routing-rules/types/routing-rules-type';
|
||||||
import { DomainThriftFormDialogComponent } from '@cc/app/shared/components/thrift-api-crud';
|
import { DomainThriftFormDialogComponent } from '@cc/app/shared/components/thrift-api-crud';
|
||||||
|
|
||||||
@ -152,10 +151,6 @@ export class RoutingRulesetComponent {
|
|||||||
]),
|
]),
|
||||||
];
|
];
|
||||||
openedCandidate?: RoutingCandidate;
|
openedCandidate?: RoutingCandidate;
|
||||||
sort: Sort = {
|
|
||||||
active: 'priority',
|
|
||||||
direction: 'desc',
|
|
||||||
};
|
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private dialog: DialogService,
|
private dialog: DialogService,
|
||||||
@ -271,7 +266,9 @@ export class RoutingRulesetComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private formatPredicate(predicate: Predicate) {
|
private formatPredicate(predicate: Predicate) {
|
||||||
if (!predicate) return '';
|
if (!predicate) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
if (getUnionKey(predicate) === 'constant') {
|
if (getUnionKey(predicate) === 'constant') {
|
||||||
return JSON.stringify(predicate.constant);
|
return JSON.stringify(predicate.constant);
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@ import cloneDeep from 'lodash-es/cloneDeep';
|
|||||||
import { combineLatest, concat, Observable } from 'rxjs';
|
import { combineLatest, concat, Observable } from 'rxjs';
|
||||||
import { map, pluck, shareReplay, switchMap, take } from 'rxjs/operators';
|
import { map, pluck, shareReplay, switchMap, take } from 'rxjs/operators';
|
||||||
|
|
||||||
import { DomainStoreService } from '@cc/app/api/deprecated-damsel';
|
import { DomainStoreService } from '@cc/app/api/domain-config';
|
||||||
import { createNextId } from '@cc/utils/create-next-id';
|
import { createNextId } from '@cc/utils/create-next-id';
|
||||||
|
|
||||||
import { getDelegate } from './utils/get-delegate';
|
import { getDelegate } from './utils/get-delegate';
|
||||||
|
@ -13,7 +13,7 @@ import { ComponentChanges } from '@vality/ng-core';
|
|||||||
import sortBy from 'lodash-es/sortBy';
|
import sortBy from 'lodash-es/sortBy';
|
||||||
import { map, startWith } from 'rxjs/operators';
|
import { map, startWith } from 'rxjs/operators';
|
||||||
|
|
||||||
import { DomainStoreService } from '@cc/app/api/deprecated-damsel';
|
import { DomainStoreService } from '@cc/app/api/domain-config';
|
||||||
|
|
||||||
import { RoutingRulesService } from '../services/routing-rules';
|
import { RoutingRulesService } from '../services/routing-rules';
|
||||||
import { RoutingRulesType } from '../types/routing-rules-type';
|
import { RoutingRulesType } from '../types/routing-rules-type';
|
||||||
|
@ -56,6 +56,10 @@ const ROUTES: Routes = [
|
|||||||
path: 'chargebacks',
|
path: 'chargebacks',
|
||||||
loadChildren: () => import('./chargebacks').then((m) => m.ChargebacksModule),
|
loadChildren: () => import('./chargebacks').then((m) => m.ChargebacksModule),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: 'terminals',
|
||||||
|
loadChildren: () => import('./terminals').then((m) => m.TerminalsModule),
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: '404',
|
path: '404',
|
||||||
loadChildren: () => import('./not-found').then((m) => m.NotFoundModule),
|
loadChildren: () => import('./not-found').then((m) => m.NotFoundModule),
|
||||||
|
2
src/app/sections/terminals/index.ts
Normal file
2
src/app/sections/terminals/index.ts
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
export * from './terminals.module';
|
||||||
|
export * from './routing-config';
|
5
src/app/sections/terminals/routing-config.ts
Normal file
5
src/app/sections/terminals/routing-config.ts
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
import { Services, RoutingConfig } from '@cc/app/shared/services';
|
||||||
|
|
||||||
|
export const ROUTING_CONFIG: RoutingConfig = {
|
||||||
|
services: [Services.Domain],
|
||||||
|
};
|
22
src/app/sections/terminals/terminals-routing.module.ts
Normal file
22
src/app/sections/terminals/terminals-routing.module.ts
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
import { NgModule } from '@angular/core';
|
||||||
|
import { RouterModule } from '@angular/router';
|
||||||
|
|
||||||
|
import { AppAuthGuardService } from '@cc/app/shared/services';
|
||||||
|
|
||||||
|
import { ROUTING_CONFIG } from './routing-config';
|
||||||
|
import { TerminalsComponent } from './terminals.component';
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
imports: [
|
||||||
|
RouterModule.forChild([
|
||||||
|
{
|
||||||
|
path: '',
|
||||||
|
component: TerminalsComponent,
|
||||||
|
canActivate: [AppAuthGuardService],
|
||||||
|
data: ROUTING_CONFIG,
|
||||||
|
},
|
||||||
|
]),
|
||||||
|
],
|
||||||
|
exports: [RouterModule],
|
||||||
|
})
|
||||||
|
export class TerminalsRoutingModule {}
|
33
src/app/sections/terminals/terminals.component.html
Normal file
33
src/app/sections/terminals/terminals.component.html
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
<cc-page-layout title="Terminals">
|
||||||
|
<cc-page-layout-actions></cc-page-layout-actions>
|
||||||
|
<v-input-field [formControl]="searchControl" label="Search"></v-input-field>
|
||||||
|
<v-table
|
||||||
|
[(sort)]="sort"
|
||||||
|
[columns]="columns"
|
||||||
|
[data]="data$ | async"
|
||||||
|
[progress]="progress$ | async"
|
||||||
|
size="50"
|
||||||
|
sortOnFront
|
||||||
|
(update)="update()"
|
||||||
|
>
|
||||||
|
<v-table-actions>
|
||||||
|
<button color="primary" mat-raised-button (click)="create()">Create</button>
|
||||||
|
</v-table-actions>
|
||||||
|
</v-table>
|
||||||
|
</cc-page-layout>
|
||||||
|
|
||||||
|
<ng-template #terminalTpl>
|
||||||
|
<cc-domain-thrift-viewer
|
||||||
|
[value]="openedTerminal"
|
||||||
|
type="TerminalObject"
|
||||||
|
></cc-domain-thrift-viewer>
|
||||||
|
</ng-template>
|
||||||
|
<ng-template #providerTpl>
|
||||||
|
<cc-domain-thrift-viewer
|
||||||
|
[value]="openedProvider"
|
||||||
|
type="ProviderObject"
|
||||||
|
></cc-domain-thrift-viewer>
|
||||||
|
</ng-template>
|
||||||
|
<ng-template #routingRulesTpl>
|
||||||
|
<v-table [columns]="routingRulesColumns" [data]="openedRoutingRules" noActions></v-table>
|
||||||
|
</ng-template>
|
240
src/app/sections/terminals/terminals.component.ts
Normal file
240
src/app/sections/terminals/terminals.component.ts
Normal file
@ -0,0 +1,240 @@
|
|||||||
|
import { Component, ViewChild, TemplateRef } from '@angular/core';
|
||||||
|
import { FormControl } from '@angular/forms';
|
||||||
|
import { Sort } from '@angular/material/sort';
|
||||||
|
import { Router } from '@angular/router';
|
||||||
|
import { untilDestroyed, UntilDestroy } from '@ngneat/until-destroy';
|
||||||
|
import {
|
||||||
|
TerminalObject,
|
||||||
|
ProviderObject,
|
||||||
|
RoutingRulesObject,
|
||||||
|
RoutingDelegate,
|
||||||
|
} from '@vality/domain-proto/domain';
|
||||||
|
import { Column } from '@vality/ng-core';
|
||||||
|
import startCase from 'lodash-es/startCase';
|
||||||
|
import { combineLatest } from 'rxjs';
|
||||||
|
import { startWith, map, debounceTime, tap, take } from 'rxjs/operators';
|
||||||
|
|
||||||
|
import { objectToJSON, createFullTextSearch, getUnionValue, getUnionKey } from '../../../utils';
|
||||||
|
import { DomainStoreService } from '../../api/domain-config';
|
||||||
|
import { PartiesStoreService } from '../../api/payment-processing';
|
||||||
|
import { SidenavInfoService } from '../../shared/components/sidenav-info';
|
||||||
|
|
||||||
|
@UntilDestroy()
|
||||||
|
@Component({
|
||||||
|
selector: 'cc-terminals',
|
||||||
|
templateUrl: './terminals.component.html',
|
||||||
|
})
|
||||||
|
export class TerminalsComponent {
|
||||||
|
searchControl = new FormControl('');
|
||||||
|
columns: Column<TerminalObject>[] = [
|
||||||
|
{ field: 'ref.id', sortable: true },
|
||||||
|
{
|
||||||
|
field: 'data.name',
|
||||||
|
description: 'data.description',
|
||||||
|
sortable: true,
|
||||||
|
click: (d) => {
|
||||||
|
this.openedTerminal = d;
|
||||||
|
this.sidenavInfoService.toggle(
|
||||||
|
this.terminalTpl,
|
||||||
|
d.data.name || d.data.description || `Terminal #${d.ref.id}`,
|
||||||
|
d,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'data.provider_ref.id',
|
||||||
|
description: 'data.provider_ref.id',
|
||||||
|
header: 'Provider',
|
||||||
|
formatter: (d) => this.getProvider(d).pipe(map((p) => p?.data?.name || '')),
|
||||||
|
sortable: true,
|
||||||
|
click: (d) => {
|
||||||
|
this.getProvider(d)
|
||||||
|
.pipe(take(1), untilDestroyed(this))
|
||||||
|
.subscribe((provider) => {
|
||||||
|
if (!provider) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.openedProvider = provider;
|
||||||
|
this.sidenavInfoService.toggle(
|
||||||
|
this.providerTpl,
|
||||||
|
provider.data.name ||
|
||||||
|
provider.data.description ||
|
||||||
|
`Provider #${provider.ref.id}`,
|
||||||
|
provider,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'delegates',
|
||||||
|
formatter: (d) =>
|
||||||
|
this.getTerminalShopWalletDelegates(d).pipe(map((r) => r.length || '')),
|
||||||
|
click: (d) => {
|
||||||
|
this.getTerminalShopWalletDelegates(d)
|
||||||
|
.pipe(take(1), untilDestroyed(this))
|
||||||
|
.subscribe((rules) => {
|
||||||
|
this.openedRoutingRules = rules;
|
||||||
|
this.sidenavInfoService.toggle(
|
||||||
|
this.routingRulesTpl,
|
||||||
|
`Terminal #${d.ref.id} delegates`,
|
||||||
|
d,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
data$ = combineLatest([
|
||||||
|
this.domainStoreService.getObjects('terminal').pipe(
|
||||||
|
map((objects) =>
|
||||||
|
createFullTextSearch(
|
||||||
|
objects,
|
||||||
|
objects.map((o) => ({
|
||||||
|
ref: o.ref.id,
|
||||||
|
data: JSON.stringify(objectToJSON(o.data)),
|
||||||
|
name: o.data.name,
|
||||||
|
description: o.data.description,
|
||||||
|
})),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
this.searchControl.valueChanges.pipe(
|
||||||
|
startWith(this.searchControl.value),
|
||||||
|
debounceTime(100),
|
||||||
|
),
|
||||||
|
]).pipe(
|
||||||
|
tap(([, search]) => {
|
||||||
|
if (search) {
|
||||||
|
this.sort = { active: '', direction: '' };
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
map(([fts, search]) => fts.search(search)),
|
||||||
|
);
|
||||||
|
progress$ = this.domainStoreService.isLoading$;
|
||||||
|
sort: Sort = { active: 'data.name', direction: 'asc' };
|
||||||
|
openedTerminal?: TerminalObject;
|
||||||
|
@ViewChild('terminalTpl') terminalTpl: TemplateRef<unknown>;
|
||||||
|
openedProvider?: ProviderObject;
|
||||||
|
@ViewChild('providerTpl') providerTpl: TemplateRef<unknown>;
|
||||||
|
openedRoutingRules?: {
|
||||||
|
delegate: RoutingDelegate;
|
||||||
|
rule: RoutingRulesObject;
|
||||||
|
terminalRule: RoutingRulesObject;
|
||||||
|
}[];
|
||||||
|
@ViewChild('routingRulesTpl') routingRulesTpl: TemplateRef<unknown>;
|
||||||
|
|
||||||
|
routingRulesColumns: Column<{
|
||||||
|
delegate: RoutingDelegate;
|
||||||
|
rule: RoutingRulesObject;
|
||||||
|
terminalRule: RoutingRulesObject;
|
||||||
|
}>[] = [
|
||||||
|
{
|
||||||
|
header: 'Routing Rule',
|
||||||
|
field: 'terminalRule.data.name',
|
||||||
|
description: 'terminalRule.ref.id',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
header: 'Ruleset',
|
||||||
|
field: 'rule.data.name',
|
||||||
|
description: 'rule.ref.id',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'party',
|
||||||
|
formatter: (d) =>
|
||||||
|
this.partiesStoreService
|
||||||
|
.get(d.delegate.allowed.condition?.party?.id)
|
||||||
|
.pipe(map((p) => p.contact_info.email)),
|
||||||
|
description: (d) => d.delegate.allowed.condition?.party?.id,
|
||||||
|
link: (d) => `/party/${d.delegate.allowed.condition.party.id}`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'type',
|
||||||
|
formatter: (d) =>
|
||||||
|
startCase(
|
||||||
|
getUnionKey(d.delegate.allowed.condition?.party?.definition).slice(0, -3),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'definition',
|
||||||
|
formatter: (d) =>
|
||||||
|
this.partiesStoreService
|
||||||
|
.get(d.delegate.allowed.condition?.party?.id)
|
||||||
|
.pipe(
|
||||||
|
map((p) =>
|
||||||
|
getUnionKey(d.delegate.allowed.condition?.party?.definition) ===
|
||||||
|
'shop_is'
|
||||||
|
? p.shops.get(
|
||||||
|
getUnionValue(
|
||||||
|
d.delegate.allowed.condition?.party?.definition,
|
||||||
|
),
|
||||||
|
).details.name
|
||||||
|
: p.wallets.get(
|
||||||
|
getUnionValue(
|
||||||
|
d.delegate.allowed.condition?.party?.definition,
|
||||||
|
),
|
||||||
|
).name,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
description: (d) => getUnionValue(d.delegate.allowed.condition?.party?.definition),
|
||||||
|
link: (d) =>
|
||||||
|
`/party/${d.delegate.allowed.condition.party.id}/routing-rules/${
|
||||||
|
getUnionKey(d.delegate.allowed.condition?.party?.definition) === 'shop_is'
|
||||||
|
? 'payment'
|
||||||
|
: 'withdrawal'
|
||||||
|
}/${d.rule.ref.id}/delegate/${d.delegate.ruleset.id}`,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
private domainStoreService: DomainStoreService,
|
||||||
|
private router: Router,
|
||||||
|
private sidenavInfoService: SidenavInfoService,
|
||||||
|
private partiesStoreService: PartiesStoreService,
|
||||||
|
) {}
|
||||||
|
|
||||||
|
update() {
|
||||||
|
this.domainStoreService.forceReload();
|
||||||
|
}
|
||||||
|
|
||||||
|
create() {
|
||||||
|
void this.router.navigate(['/domain/create']);
|
||||||
|
}
|
||||||
|
|
||||||
|
private getProvider(terminalObj: TerminalObject) {
|
||||||
|
return this.domainStoreService
|
||||||
|
.getObjects('provider')
|
||||||
|
.pipe(
|
||||||
|
map((providers) =>
|
||||||
|
providers.find((p) => p.ref.id === terminalObj.data.provider_ref.id),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private getTerminalShopWalletDelegates(terminalObj: TerminalObject) {
|
||||||
|
return this.domainStoreService.getObjects('routing_rules').pipe(
|
||||||
|
map((rules) => {
|
||||||
|
const terminalRules = rules.filter(
|
||||||
|
(r) =>
|
||||||
|
r.data?.decisions?.candidates?.some?.(
|
||||||
|
(c) => c.terminal.id === terminalObj.ref.id,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
return terminalRules
|
||||||
|
.map((terminalRule) =>
|
||||||
|
rules.map((rule) =>
|
||||||
|
(
|
||||||
|
rule?.data?.decisions?.delegates?.filter?.(
|
||||||
|
(d) =>
|
||||||
|
d?.ruleset?.id === terminalRule.ref.id &&
|
||||||
|
d?.allowed?.condition?.party &&
|
||||||
|
['wallet_is', 'shop_is'].includes(
|
||||||
|
getUnionKey(d?.allowed?.condition?.party?.definition),
|
||||||
|
),
|
||||||
|
) || []
|
||||||
|
).map((delegate) => ({ delegate, rule, terminalRule })),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.flat(2);
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
28
src/app/sections/terminals/terminals.module.ts
Normal file
28
src/app/sections/terminals/terminals.module.ts
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
import { CommonModule } from '@angular/common';
|
||||||
|
import { NgModule } from '@angular/core';
|
||||||
|
import { ReactiveFormsModule } from '@angular/forms';
|
||||||
|
import { MatButtonModule } from '@angular/material/button';
|
||||||
|
import { MatExpansionModule } from '@angular/material/expansion';
|
||||||
|
import { TableModule, InputFieldModule } from '@vality/ng-core';
|
||||||
|
|
||||||
|
import { PageLayoutModule } from '../../shared';
|
||||||
|
import { DomainThriftViewerComponent } from '../../shared/components/thrift-api-crud';
|
||||||
|
|
||||||
|
import { TerminalsRoutingModule } from './terminals-routing.module';
|
||||||
|
import { TerminalsComponent } from './terminals.component';
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
declarations: [TerminalsComponent],
|
||||||
|
imports: [
|
||||||
|
CommonModule,
|
||||||
|
TerminalsRoutingModule,
|
||||||
|
TableModule,
|
||||||
|
MatButtonModule,
|
||||||
|
PageLayoutModule,
|
||||||
|
InputFieldModule,
|
||||||
|
ReactiveFormsModule,
|
||||||
|
DomainThriftViewerComponent,
|
||||||
|
MatExpansionModule,
|
||||||
|
],
|
||||||
|
})
|
||||||
|
export class TerminalsModule {}
|
@ -41,8 +41,11 @@ export class DatetimeComponent extends FormComponentSuperclass<string> {
|
|||||||
|
|
||||||
dateChanged(date: MatDatepickerInputEvent<Moment>) {
|
dateChanged(date: MatDatepickerInputEvent<Moment>) {
|
||||||
const v = date.target.value;
|
const v = date.target.value;
|
||||||
if (!this.datetime) this.datetime = date.target.value;
|
if (!this.datetime) {
|
||||||
else this.datetime.set({ date: v.date(), month: v.month(), year: v.year() });
|
this.datetime = date.target.value;
|
||||||
|
} else {
|
||||||
|
this.datetime.set({ date: v.date(), month: v.month(), year: v.year() });
|
||||||
|
}
|
||||||
this.emitOutgoingValue(this.datetime.toISOString());
|
this.emitOutgoingValue(this.datetime.toISOString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,11 +15,15 @@ export class KeyComponent implements OnChanges {
|
|||||||
keys$ = new ReplaySubject<MetadataViewItem[]>(1);
|
keys$ = new ReplaySubject<MetadataViewItem[]>(1);
|
||||||
numberKey$ = this.keys$.pipe(
|
numberKey$ = this.keys$.pipe(
|
||||||
switchMap((keys) => {
|
switchMap((keys) => {
|
||||||
if (keys.length !== 1) return of(null);
|
if (keys.length !== 1) {
|
||||||
|
return of(null);
|
||||||
|
}
|
||||||
return this.keys[0].key$.pipe(
|
return this.keys[0].key$.pipe(
|
||||||
switchMap((key) => key.renderValue$),
|
switchMap((key) => key.renderValue$),
|
||||||
map((value) => {
|
map((value) => {
|
||||||
if (typeof value === 'number') return `${value + 1}`;
|
if (typeof value === 'number') {
|
||||||
|
return `${value + 1}`;
|
||||||
|
}
|
||||||
return null;
|
return null;
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
@ -27,16 +31,22 @@ export class KeyComponent implements OnChanges {
|
|||||||
);
|
);
|
||||||
|
|
||||||
ngOnChanges(changes: ComponentChanges<KeyComponent>) {
|
ngOnChanges(changes: ComponentChanges<KeyComponent>) {
|
||||||
if (changes.keys) this.keys$.next(this.keys);
|
if (changes.keys) {
|
||||||
|
this.keys$.next(this.keys);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
parentIsUnion(pathItem: MetadataViewItem) {
|
parentIsUnion(pathItem: MetadataViewItem) {
|
||||||
if (!pathItem?.data$) return of(false);
|
if (!pathItem?.data$) {
|
||||||
|
return of(false);
|
||||||
|
}
|
||||||
return pathItem.data$.pipe(map((data) => data?.trueParent?.objectType === 'union'));
|
return pathItem.data$.pipe(map((data) => data?.trueParent?.objectType === 'union'));
|
||||||
}
|
}
|
||||||
|
|
||||||
isUnion(pathItem: MetadataViewItem) {
|
isUnion(pathItem: MetadataViewItem) {
|
||||||
if (!pathItem?.data$) return of(false);
|
if (!pathItem?.data$) {
|
||||||
|
return of(false);
|
||||||
|
}
|
||||||
return pathItem.data$.pipe(map((data) => data?.trueTypeNode?.data?.objectType === 'union'));
|
return pathItem.data$.pipe(map((data) => data?.trueTypeNode?.data?.objectType === 'union'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
export function getEntries(obj: unknown): [number | string, unknown][] {
|
export function getEntries(obj: unknown): [number | string, unknown][] {
|
||||||
if (!obj) return [];
|
if (!obj) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
return Array.isArray(obj) || obj instanceof Set
|
return Array.isArray(obj) || obj instanceof Set
|
||||||
? Array.from(obj).map((v, idx) => [idx, v])
|
? Array.from(obj).map((v, idx) => [idx, v])
|
||||||
: obj instanceof Map
|
: obj instanceof Map
|
||||||
|
@ -31,17 +31,21 @@ export class MetadataViewItem {
|
|||||||
);
|
);
|
||||||
renderValue$ = combineLatest([this.value$, this.data$]).pipe(
|
renderValue$ = combineLatest([this.value$, this.data$]).pipe(
|
||||||
map(([value, data]) => {
|
map(([value, data]) => {
|
||||||
if (data?.trueTypeNode?.data?.objectType === 'enum')
|
if (data?.trueTypeNode?.data?.objectType === 'enum') {
|
||||||
return (
|
return (
|
||||||
(data.trueTypeNode.data as MetadataFormData<ValueType, 'enum'>).ast.items.find(
|
(data.trueTypeNode.data as MetadataFormData<ValueType, 'enum'>).ast.items.find(
|
||||||
(i, idx) => {
|
(i, idx) => {
|
||||||
if ('value' in i) return i.value === value;
|
if ('value' in i) {
|
||||||
|
return i.value === value;
|
||||||
|
}
|
||||||
return idx === value;
|
return idx === value;
|
||||||
},
|
},
|
||||||
).name ?? value
|
).name ?? value
|
||||||
);
|
);
|
||||||
if (data?.objectType === 'union' && isEmpty(getEntries(value)?.[0]?.[1]))
|
}
|
||||||
|
if (data?.objectType === 'union' && isEmpty(getEntries(value)?.[0]?.[1])) {
|
||||||
return getEntries(value)?.[0]?.[0];
|
return getEntries(value)?.[0]?.[0];
|
||||||
|
}
|
||||||
return value;
|
return value;
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
@ -64,8 +68,9 @@ export class MetadataViewItem {
|
|||||||
key?.data ||
|
key?.data ||
|
||||||
(data?.trueTypeNode?.data as MetadataFormData<SetType | ListType | MapType>)?.type
|
(data?.trueTypeNode?.data as MetadataFormData<SetType | ListType | MapType>)?.type
|
||||||
?.name
|
?.name
|
||||||
)
|
) {
|
||||||
return of([]);
|
return of([]);
|
||||||
|
}
|
||||||
const [item] = items;
|
const [item] = items;
|
||||||
return combineLatest([
|
return combineLatest([
|
||||||
item.key$.pipe(switchMap((key) => key.value$)),
|
item.key$.pipe(switchMap((key) => key.value$)),
|
||||||
@ -75,12 +80,14 @@ export class MetadataViewItem {
|
|||||||
if (
|
if (
|
||||||
typeof childKey === 'number' ||
|
typeof childKey === 'number' ||
|
||||||
(data?.objectType === 'union' && isEmpty(childValue))
|
(data?.objectType === 'union' && isEmpty(childValue))
|
||||||
)
|
) {
|
||||||
return of([]);
|
return of([]);
|
||||||
|
}
|
||||||
return item.data$.pipe(
|
return item.data$.pipe(
|
||||||
switchMap((itemData) => {
|
switchMap((itemData) => {
|
||||||
if (data?.objectType === 'union' && itemData?.objectType !== 'union')
|
if (data?.objectType === 'union' && itemData?.objectType !== 'union') {
|
||||||
return of([item]);
|
return of([item]);
|
||||||
|
}
|
||||||
return item.inline$.pipe(map((childInline) => [item, ...childInline]));
|
return item.inline$.pipe(map((childInline) => [item, ...childInline]));
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
@ -56,7 +56,9 @@ export class MerchantFieldComponent
|
|||||||
}
|
}
|
||||||
|
|
||||||
private searchOptions(str: string): Observable<Option<PartyID>[]> {
|
private searchOptions(str: string): Observable<Option<PartyID>[]> {
|
||||||
if (!str) return of([]);
|
if (!str) {
|
||||||
|
return of([]);
|
||||||
|
}
|
||||||
return this.deanonimusService.searchParty(str).pipe(
|
return this.deanonimusService.searchParty(str).pipe(
|
||||||
map((parties) =>
|
map((parties) =>
|
||||||
parties.map((p) => ({
|
parties.map((p) => ({
|
||||||
|
@ -52,7 +52,9 @@ export class ComplexFormComponent<V, K = never>
|
|||||||
}
|
}
|
||||||
|
|
||||||
get keyType() {
|
get keyType() {
|
||||||
if ('keyType' in this.data.type) return this.data.type.keyType;
|
if ('keyType' in this.data.type) {
|
||||||
|
return this.data.type.keyType;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
@ -93,11 +95,15 @@ export class ComplexFormComponent<V, K = never>
|
|||||||
|
|
||||||
add() {
|
add() {
|
||||||
this.valueControls.push(new FormControl());
|
this.valueControls.push(new FormControl());
|
||||||
if (this.isKeyValue) this.keyControls.push(new FormControl());
|
if (this.isKeyValue) {
|
||||||
|
this.keyControls.push(new FormControl());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
delete(idx: number) {
|
delete(idx: number) {
|
||||||
this.valueControls.removeAt(idx);
|
this.valueControls.removeAt(idx);
|
||||||
if (this.isKeyValue) this.keyControls.removeAt(idx);
|
if (this.isKeyValue) {
|
||||||
|
this.keyControls.removeAt(idx);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -89,7 +89,9 @@ export class ExtensionFieldComponent<T>
|
|||||||
this.data$.next(this.data);
|
this.data$.next(this.data);
|
||||||
this.control.setValidators(this.data.isRequired ? Validators.required : []);
|
this.control.setValidators(this.data.isRequired ? Validators.required : []);
|
||||||
}
|
}
|
||||||
if (changes.extensions) this.extensions$.next(this.extensions);
|
if (changes.extensions) {
|
||||||
|
this.extensions$.next(this.extensions);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
generate(event: MouseEvent) {
|
generate(event: MouseEvent) {
|
||||||
|
@ -82,8 +82,12 @@ export class PrimitiveFieldComponent<T>
|
|||||||
|
|
||||||
ngOnChanges(changes: ComponentChanges<PrimitiveFieldComponent<T>>) {
|
ngOnChanges(changes: ComponentChanges<PrimitiveFieldComponent<T>>) {
|
||||||
super.ngOnChanges(changes);
|
super.ngOnChanges(changes);
|
||||||
if (changes.data) this.data$.next(this.data);
|
if (changes.data) {
|
||||||
if (changes.extensions) this.extensions$.next(this.extensions);
|
this.data$.next(this.data);
|
||||||
|
}
|
||||||
|
if (changes.extensions) {
|
||||||
|
this.extensions$.next(this.extensions);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
generate(event: MouseEvent) {
|
generate(event: MouseEvent) {
|
||||||
|
@ -55,8 +55,11 @@ export class StructFormComponent<T extends { [N in string]: unknown }>
|
|||||||
ngOnChanges(changes: SimpleChanges) {
|
ngOnChanges(changes: SimpleChanges) {
|
||||||
const newControlsNames = new Set(this.data.ast.map(({ name }) => name));
|
const newControlsNames = new Set(this.data.ast.map(({ name }) => name));
|
||||||
Object.keys(this.control.controls).forEach((name) => {
|
Object.keys(this.control.controls).forEach((name) => {
|
||||||
if (newControlsNames.has(name)) newControlsNames.delete(name);
|
if (newControlsNames.has(name)) {
|
||||||
else this.control.removeControl(name as never);
|
newControlsNames.delete(name);
|
||||||
|
} else {
|
||||||
|
this.control.removeControl(name as never);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
newControlsNames.forEach((name) =>
|
newControlsNames.forEach((name) =>
|
||||||
this.control.addControl(
|
this.control.addControl(
|
||||||
@ -84,11 +87,19 @@ export class StructFormComponent<T extends { [N in string]: unknown }>
|
|||||||
|
|
||||||
private setLabelControl(value: boolean = false) {
|
private setLabelControl(value: boolean = false) {
|
||||||
if (!this.hasLabel || this.data.isRequired) {
|
if (!this.hasLabel || this.data.isRequired) {
|
||||||
if (!this.labelControl.value) this.labelControl.setValue(true);
|
if (!this.labelControl.value) {
|
||||||
if (this.labelControl.enabled) this.labelControl.disable();
|
this.labelControl.setValue(true);
|
||||||
|
}
|
||||||
|
if (this.labelControl.enabled) {
|
||||||
|
this.labelControl.disable();
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if (this.labelControl.value !== value) this.labelControl.setValue(value);
|
if (this.labelControl.value !== value) {
|
||||||
if (this.labelControl.disabled) this.labelControl.enable();
|
this.labelControl.setValue(value);
|
||||||
|
}
|
||||||
|
if (this.labelControl.disabled) {
|
||||||
|
this.labelControl.enable();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -98,7 +98,9 @@ export class MetadataFormData<
|
|||||||
) {
|
) {
|
||||||
this.setNamespaceType(namespace, type);
|
this.setNamespaceType(namespace, type);
|
||||||
this.setTypeGroup();
|
this.setTypeGroup();
|
||||||
if (this.typeGroup === TypeGroup.Object) this.setNamespaceObjectType();
|
if (this.typeGroup === TypeGroup.Object) {
|
||||||
|
this.setNamespaceObjectType();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
create(params: { type?: ValueType; field?: Field }): MetadataFormData {
|
create(params: { type?: ValueType; field?: Field }): MetadataFormData {
|
||||||
|
@ -12,7 +12,7 @@ import {
|
|||||||
import { defer, switchMap, ReplaySubject } from 'rxjs';
|
import { defer, switchMap, ReplaySubject } from 'rxjs';
|
||||||
import { shareReplay, map } from 'rxjs/operators';
|
import { shareReplay, map } from 'rxjs/operators';
|
||||||
|
|
||||||
import { DomainStoreService } from '@cc/app/api/deprecated-damsel';
|
import { DomainStoreService } from '@cc/app/api/domain-config';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
DOMAIN_OBJECTS_TO_OPTIONS,
|
DOMAIN_OBJECTS_TO_OPTIONS,
|
||||||
|
@ -8,7 +8,7 @@ import isEqual from 'lodash-es/isEqual';
|
|||||||
import { of, Observable } from 'rxjs';
|
import { of, Observable } from 'rxjs';
|
||||||
import { map, shareReplay } from 'rxjs/operators';
|
import { map, shareReplay } from 'rxjs/operators';
|
||||||
|
|
||||||
import { DomainStoreService } from '@cc/app/api/deprecated-damsel';
|
import { DomainStoreService } from '@cc/app/api/domain-config';
|
||||||
import { MetadataViewExtension } from '@cc/app/shared/components/json-viewer';
|
import { MetadataViewExtension } from '@cc/app/shared/components/json-viewer';
|
||||||
import { isTypeWithAliases, MetadataFormData } from '@cc/app/shared/components/metadata-form';
|
import { isTypeWithAliases, MetadataFormData } from '@cc/app/shared/components/metadata-form';
|
||||||
|
|
||||||
|
@ -12,8 +12,12 @@ const LABEL_SELECTORS: {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export function getObjectLabel(o: DomainObject[keyof DomainObject], objectKey: keyof DomainObject) {
|
export function getObjectLabel(o: DomainObject[keyof DomainObject], objectKey: keyof DomainObject) {
|
||||||
if (LABEL_SELECTORS[objectKey]) return LABEL_SELECTORS[objectKey](o as never);
|
if (LABEL_SELECTORS[objectKey]) {
|
||||||
if ('name' in o.data && o.data.name) return o.data.name;
|
return LABEL_SELECTORS[objectKey](o as never);
|
||||||
|
}
|
||||||
|
if ('name' in o.data && o.data.name) {
|
||||||
|
return o.data.name;
|
||||||
|
}
|
||||||
const id = 'id' in o.ref && typeof o.ref.id !== 'object' ? o.ref.id : '';
|
const id = 'id' in o.ref && typeof o.ref.id !== 'object' ? o.ref.id : '';
|
||||||
return startCase([...objectKey.split('_'), 'ref', id && `#${id}`].filter(Boolean).join(' '));
|
return startCase([...objectKey.split('_'), 'ref', id && `#${id}`].filter(Boolean).join(' '));
|
||||||
}
|
}
|
||||||
|
@ -15,5 +15,6 @@
|
|||||||
.monaco-editor {
|
.monaco-editor {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
display: block;
|
display: block;
|
||||||
|
min-height: 300px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@ import isNil from 'lodash-es/isNil';
|
|||||||
import { ReplaySubject, combineLatest } from 'rxjs';
|
import { ReplaySubject, combineLatest } from 'rxjs';
|
||||||
import { map, startWith } from 'rxjs/operators';
|
import { map, startWith } from 'rxjs/operators';
|
||||||
|
|
||||||
import { DomainStoreService } from '@cc/app/api/deprecated-damsel';
|
import { DomainStoreService } from '@cc/app/api/domain-config';
|
||||||
|
|
||||||
import { toMajor } from '../../../utils';
|
import { toMajor } from '../../../utils';
|
||||||
|
|
||||||
@ -39,10 +39,12 @@ export class AmountCurrencyPipe implements PipeTransform {
|
|||||||
])
|
])
|
||||||
.pipe(
|
.pipe(
|
||||||
map(([currencies, { amount, currencyCode, format }]) => {
|
map(([currencies, { amount, currencyCode, format }]) => {
|
||||||
if (isNil(amount)) return '?';
|
if (isNil(amount)) {
|
||||||
|
return '?';
|
||||||
|
}
|
||||||
const exponent = currencies.find((c) => c.data.symbolic_code === currencyCode)
|
const exponent = currencies.find((c) => c.data.symbolic_code === currencyCode)
|
||||||
?.data?.exponent;
|
?.data?.exponent;
|
||||||
if (!currencyCode || !exponent)
|
if (!currencyCode || !exponent) {
|
||||||
return formatCurrency(
|
return formatCurrency(
|
||||||
toMajor(amount, exponent),
|
toMajor(amount, exponent),
|
||||||
this._locale,
|
this._locale,
|
||||||
@ -50,6 +52,7 @@ export class AmountCurrencyPipe implements PipeTransform {
|
|||||||
'',
|
'',
|
||||||
format === 'short' ? '0.0-2' : undefined,
|
format === 'short' ? '0.0-2' : undefined,
|
||||||
);
|
);
|
||||||
|
}
|
||||||
return formatCurrency(
|
return formatCurrency(
|
||||||
toMajor(amount, exponent),
|
toMajor(amount, exponent),
|
||||||
this._locale,
|
this._locale,
|
||||||
@ -71,7 +74,9 @@ export class AmountCurrencyPipe implements PipeTransform {
|
|||||||
format: 'short' | 'long' = 'long',
|
format: 'short' | 'long' = 'long',
|
||||||
) {
|
) {
|
||||||
this.params$.next({ amount, currencyCode, format });
|
this.params$.next({ amount, currencyCode, format });
|
||||||
if (!this.isInit) this.init();
|
if (!this.isInit) {
|
||||||
|
this.init();
|
||||||
|
}
|
||||||
return this.latestValue;
|
return this.latestValue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@ import { Injectable } from '@angular/core';
|
|||||||
import { toMajorByExponent } from '@vality/ng-core';
|
import { toMajorByExponent } from '@vality/ng-core';
|
||||||
import { map, first } from 'rxjs/operators';
|
import { map, first } from 'rxjs/operators';
|
||||||
|
|
||||||
import { DomainStoreService } from '@cc/app/api/deprecated-damsel';
|
import { DomainStoreService } from '@cc/app/api/domain-config';
|
||||||
|
|
||||||
@Injectable({
|
@Injectable({
|
||||||
providedIn: 'root',
|
providedIn: 'root',
|
||||||
|
@ -25,8 +25,9 @@ export class AppAuthGuardService extends KeycloakAuthGuard {
|
|||||||
}
|
}
|
||||||
|
|
||||||
userHasSomeServiceMethods(serviceMethods: string[]): boolean {
|
userHasSomeServiceMethods(serviceMethods: string[]): boolean {
|
||||||
if ((!environment.production && environment.ignoreRoles) || !serviceMethods?.length)
|
if ((!environment.production && environment.ignoreRoles) || !serviceMethods?.length) {
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
const allowedServiceMethods = this.keycloakAngular
|
const allowedServiceMethods = this.keycloakAngular
|
||||||
.getUserRoles(true)
|
.getUserRoles(true)
|
||||||
.map((r) => r.split(':'));
|
.map((r) => r.split(':'));
|
||||||
|
@ -6,7 +6,7 @@ import { from, Observable, of } from 'rxjs';
|
|||||||
import { map, shareReplay } from 'rxjs/operators';
|
import { map, shareReplay } from 'rxjs/operators';
|
||||||
import * as short from 'short-uuid';
|
import * as short from 'short-uuid';
|
||||||
|
|
||||||
import { DomainStoreService } from '@cc/app/api/deprecated-damsel';
|
import { DomainStoreService } from '@cc/app/api/domain-config';
|
||||||
|
|
||||||
import { Cash as CashField } from '../../../../components/cash-field';
|
import { Cash as CashField } from '../../../../components/cash-field';
|
||||||
import {
|
import {
|
||||||
|
@ -26,7 +26,11 @@ export const DOMAIN_OBJECTS_TO_OPTIONS: {
|
|||||||
|
|
||||||
export function defaultDomainObjectToOption(o: DomainRefDataObjects[keyof DomainRefDataObjects]) {
|
export function defaultDomainObjectToOption(o: DomainRefDataObjects[keyof DomainRefDataObjects]) {
|
||||||
let label: string;
|
let label: string;
|
||||||
if ('name' in o.data) label = o.data.name;
|
if ('name' in o.data) {
|
||||||
if ('id' in o.data && !label) label = (o.data as unknown as { id: string }).id;
|
label = o.data.name;
|
||||||
|
}
|
||||||
|
if ('id' in o.data && !label) {
|
||||||
|
label = (o.data as unknown as { id: string }).id;
|
||||||
|
}
|
||||||
return { value: o.ref.id, label, details: o };
|
return { value: o.ref.id, label, details: o };
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,9 @@ import { clean, isEmpty } from '@vality/ng-core';
|
|||||||
import isObject from 'lodash-es/isObject';
|
import isObject from 'lodash-es/isObject';
|
||||||
|
|
||||||
function isEmptyThrift(value: unknown): boolean {
|
function isEmptyThrift(value: unknown): boolean {
|
||||||
if (isObject(value) && value.constructor === Object) return false;
|
if (isObject(value) && value.constructor === Object) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
return isEmpty(value);
|
return isEmpty(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,9 +27,13 @@ export const DEFAULT_QUERY_PARAMS_SERIALIZERS: Serializer[] = [
|
|||||||
return { start, end };
|
return { start, end };
|
||||||
},
|
},
|
||||||
recognize: (value) => {
|
recognize: (value) => {
|
||||||
if (typeof value !== 'object') return false;
|
if (typeof value !== 'object') {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
const { start, end, ...other } = value as DateRange<Moment>;
|
const { start, end, ...other } = value as DateRange<Moment>;
|
||||||
if (Object.keys(other).length) return false;
|
if (Object.keys(other).length) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
return (!start || moment.isMoment(start)) && (!end || moment.isMoment(end));
|
return (!start || moment.isMoment(start)) && (!end || moment.isMoment(end));
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -9,7 +9,7 @@ import sortBy from 'lodash-es/sortBy';
|
|||||||
import { combineLatest } from 'rxjs';
|
import { combineLatest } from 'rxjs';
|
||||||
import { map, switchMap, first, distinctUntilChanged } from 'rxjs/operators';
|
import { map, switchMap, first, distinctUntilChanged } from 'rxjs/operators';
|
||||||
|
|
||||||
import { DomainStoreService } from '@cc/app/api/deprecated-damsel';
|
import { DomainStoreService } from '@cc/app/api/domain-config';
|
||||||
|
|
||||||
import { createControlProviders, getFormValueChanges } from '../../utils';
|
import { createControlProviders, getFormValueChanges } from '../../utils';
|
||||||
|
|
||||||
@ -87,10 +87,11 @@ export class CashFieldComponent extends FormComponentSuperclass<Cash> implements
|
|||||||
const amountStr = this.amountControl.value;
|
const amountStr = this.amountControl.value;
|
||||||
if (amountStr && currency && !this.validate()) {
|
if (amountStr && currency && !this.validate()) {
|
||||||
const [whole, fractional] = amountStr.split('.');
|
const [whole, fractional] = amountStr.split('.');
|
||||||
if (fractional?.length > currency.data.exponent)
|
if (fractional?.length > currency.data.exponent) {
|
||||||
this.amountControl.setValue(
|
this.amountControl.setValue(
|
||||||
`${whole}.${fractional.slice(0, currency.data.exponent)}`,
|
`${whole}.${fractional.slice(0, currency.data.exponent)}`,
|
||||||
);
|
);
|
||||||
|
}
|
||||||
const amount = Number(this.amountControl.value.replaceAll(GROUP_SEPARATOR, ''));
|
const amount = Number(this.amountControl.value.replaceAll(GROUP_SEPARATOR, ''));
|
||||||
this.emitOutgoingValue({ amount, currencyCode: currency.data.symbolic_code });
|
this.emitOutgoingValue({ amount, currencyCode: currency.data.symbolic_code });
|
||||||
} else {
|
} else {
|
||||||
|
@ -61,7 +61,9 @@ export abstract class AbstractMonacoService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
destroy() {
|
destroy() {
|
||||||
if (this.resizeDetector) this.resizeDetector.detach();
|
if (this.resizeDetector) {
|
||||||
|
this.resizeDetector.detach();
|
||||||
|
}
|
||||||
this.destroy$.next();
|
this.destroy$.next();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -153,7 +155,9 @@ export abstract class AbstractMonacoService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private registerResizeListener() {
|
private registerResizeListener() {
|
||||||
if (this.resizeDetector) this.resizeDetector.detach();
|
if (this.resizeDetector) {
|
||||||
|
this.resizeDetector.detach();
|
||||||
|
}
|
||||||
this.resizeDetector = new ResizeSensor(this.nativeElement, () => {
|
this.resizeDetector = new ResizeSensor(this.nativeElement, () => {
|
||||||
this.updateLayoutSize();
|
this.updateLayoutSize();
|
||||||
});
|
});
|
||||||
|
@ -2,7 +2,9 @@ export function unifyCsvItems<T>(
|
|||||||
csv: T[] | string[][],
|
csv: T[] | string[][],
|
||||||
defaultProps: readonly (keyof T)[] | (keyof T)[],
|
defaultProps: readonly (keyof T)[] | (keyof T)[],
|
||||||
): T[] {
|
): T[] {
|
||||||
if (!Array.isArray(csv)) return [];
|
if (!Array.isArray(csv)) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
if (Array.isArray(csv?.[0])) {
|
if (Array.isArray(csv?.[0])) {
|
||||||
return csv.map((d) =>
|
return csv.map((d) =>
|
||||||
Object.fromEntries(d.map((prop, idx) => [defaultProps[idx], prop])),
|
Object.fromEntries(d.map((prop, idx) => [defaultProps[idx], prop])),
|
||||||
|
@ -40,11 +40,14 @@ export abstract class ValidatedControlSuperclass<OuterType, InnerType = OuterTyp
|
|||||||
|
|
||||||
protected outerToInnerValue(outer: OuterType): InnerType {
|
protected outerToInnerValue(outer: OuterType): InnerType {
|
||||||
if ('controls' in this.control) {
|
if ('controls' in this.control) {
|
||||||
if (!outer) return this.emptyValue;
|
if (!outer) {
|
||||||
|
return this.emptyValue;
|
||||||
|
}
|
||||||
if (
|
if (
|
||||||
Object.keys(outer).length < Object.keys((this.control as FormGroup).controls).length
|
Object.keys(outer).length < Object.keys((this.control as FormGroup).controls).length
|
||||||
)
|
) {
|
||||||
return Object.assign({}, this.emptyValue, outer);
|
return Object.assign({}, this.emptyValue, outer);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return outer as never;
|
return outer as never;
|
||||||
}
|
}
|
||||||
|
12
src/utils/full-text-search/create-full-text-search.ts
Normal file
12
src/utils/full-text-search/create-full-text-search.ts
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
import Fuse from 'fuse.js';
|
||||||
|
|
||||||
|
export function createFullTextSearch<T extends object, O extends object>(
|
||||||
|
source: T[],
|
||||||
|
objects: O[],
|
||||||
|
options: Fuse.IFuseOptions<O> = { keys: Object.keys(objects[0]) },
|
||||||
|
) {
|
||||||
|
const fuse = new Fuse(objects, options);
|
||||||
|
return {
|
||||||
|
search: (str: string) => (str ? fuse.search(str).map((r) => source[r.refIndex]) : source),
|
||||||
|
};
|
||||||
|
}
|
1
src/utils/full-text-search/index.ts
Normal file
1
src/utils/full-text-search/index.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
export * from './create-full-text-search';
|
@ -4,9 +4,13 @@ export function getEnumEntries<E extends Record<PropertyKey, unknown>>(
|
|||||||
srcEnum: E,
|
srcEnum: E,
|
||||||
): [key: keyof E, value: ValuesType<E>][] {
|
): [key: keyof E, value: ValuesType<E>][] {
|
||||||
const entries = Object.entries(srcEnum);
|
const entries = Object.entries(srcEnum);
|
||||||
if (!entries.length) return [];
|
if (!entries.length) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
const isValueNumberEnum = entries.some(([, v]) => typeof v === 'number');
|
const isValueNumberEnum = entries.some(([, v]) => typeof v === 'number');
|
||||||
if (isValueNumberEnum) return entries.filter(([, v]) => typeof v === 'number') as never;
|
if (isValueNumberEnum) {
|
||||||
|
return entries.filter(([, v]) => typeof v === 'number') as never;
|
||||||
|
}
|
||||||
return entries as never;
|
return entries as never;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,3 +16,4 @@ export * from './enumerate';
|
|||||||
export * from './thrift-instance';
|
export * from './thrift-instance';
|
||||||
export * from './csv';
|
export * from './csv';
|
||||||
export * from './thrift';
|
export * from './thrift';
|
||||||
|
export * from './full-text-search';
|
||||||
|
@ -44,10 +44,12 @@ export function parseNamespaceObjectType(
|
|||||||
): NamespaceObjectType {
|
): NamespaceObjectType {
|
||||||
// metadata reverse find - search for the last matching protocol if the names match (files are overwritten in the same order)
|
// metadata reverse find - search for the last matching protocol if the names match (files are overwritten in the same order)
|
||||||
let namespaceMetadata: ThriftAstMetadata;
|
let namespaceMetadata: ThriftAstMetadata;
|
||||||
if (include)
|
if (include) {
|
||||||
namespaceMetadata = metadata.reverse().find((m) => m.path === include[namespace].path);
|
namespaceMetadata = metadata.reverse().find((m) => m.path === include[namespace].path);
|
||||||
if (!namespaceMetadata)
|
}
|
||||||
|
if (!namespaceMetadata) {
|
||||||
namespaceMetadata = metadata.reverse().find((m) => m.name === namespace);
|
namespaceMetadata = metadata.reverse().find((m) => m.name === namespace);
|
||||||
|
}
|
||||||
const objectType = Object.keys(namespaceMetadata.ast).find(
|
const objectType = Object.keys(namespaceMetadata.ast).find(
|
||||||
(t) => namespaceMetadata.ast[t][type],
|
(t) => namespaceMetadata.ast[t][type],
|
||||||
) as StructureType;
|
) as StructureType;
|
||||||
|
@ -2,6 +2,8 @@ import isNil from 'lodash-es/isNil';
|
|||||||
import round from 'lodash-es/round';
|
import round from 'lodash-es/round';
|
||||||
|
|
||||||
export const toMajor = (amount: number, exponent = 2): number | null => {
|
export const toMajor = (amount: number, exponent = 2): number | null => {
|
||||||
if (isNil(amount)) return null;
|
if (isNil(amount)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
return round(amount / 10 ** exponent, exponent);
|
return round(amount / 10 ** exponent, exponent);
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user