mirror of
https://github.com/valitydev/dashboard.git
synced 2024-11-06 02:25:23 +00:00
OPS-235, OPS-237: Support API's partyID, fix first entrance (#109)
This commit is contained in:
parent
a56d987843
commit
12cbb6bbe5
95
package-lock.json
generated
95
package-lock.json
generated
@ -31,14 +31,13 @@
|
||||
"@sentry/angular": "7.7.0",
|
||||
"@sentry/integrations": "7.7.0",
|
||||
"@sentry/tracing": "7.7.0",
|
||||
"@vality/swag-anapi-v2": "2.0.1-0405be2.0",
|
||||
"@vality/swag-anapi-v2": "2.0.1-38f360b.0",
|
||||
"@vality/swag-claim-management": "0.1.1-bfc2e6c.0",
|
||||
"@vality/swag-dark-api": "0.1.1-a3f1678.0",
|
||||
"@vality/swag-organizations": "1.0.1-cd6cc10.0",
|
||||
"@vality/swag-payments": "0.1.1-d71aebc.0",
|
||||
"@vality/swag-questionary-aggr-proxy": "0.1.1-1dc5add.0",
|
||||
"@vality/swag-questionary-aggr-proxy": "0.1.1-ed41741.0",
|
||||
"@vality/swag-url-shortener": "0.1.1-f780d07.0",
|
||||
"@vality/swag-wallet": "0.1.1-9a236df.0",
|
||||
"@vality/swag-wallet": "0.1.2-21b69d2.0",
|
||||
"angular-epic-spinners": "2.0.0",
|
||||
"angular-file": "^3.0.1",
|
||||
"angular2-text-mask": "^9.0.0",
|
||||
@ -85,6 +84,7 @@
|
||||
"@typescript-eslint/eslint-plugin": "5.31.0",
|
||||
"@typescript-eslint/parser": "5.31.0",
|
||||
"concurrently": "7.0.0",
|
||||
"cross-env": "^7.0.3",
|
||||
"dotenv": "^16.0.3",
|
||||
"eslint": "8.20.0",
|
||||
"eslint-config-prettier": "8.5.0",
|
||||
@ -4980,15 +4980,15 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@vality/swag-anapi-v2": {
|
||||
"version": "2.0.1-0405be2.0",
|
||||
"resolved": "https://registry.npmjs.org/@vality/swag-anapi-v2/-/swag-anapi-v2-2.0.1-0405be2.0.tgz",
|
||||
"integrity": "sha512-YHSMYjTByWVTiTyO1U+I6Rfwm6N1KUz3F4rPiG4WJRcjVut73nvoo1A1xCp5KC38qhQ7li+uTpGQ/kx8VaL5oQ==",
|
||||
"version": "2.0.1-38f360b.0",
|
||||
"resolved": "https://registry.npmjs.org/@vality/swag-anapi-v2/-/swag-anapi-v2-2.0.1-38f360b.0.tgz",
|
||||
"integrity": "sha512-6RCpXFDvD+BlKsQxrA2pDH6B9fyzp+X69zapNpTgmTsxeS5acR7Jf9MS+a0kL2Rz/B9HS86jt+VYk3pvQco/PQ==",
|
||||
"dependencies": {
|
||||
"tslib": "^2.3.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@angular/common": "^13.0.0",
|
||||
"@angular/core": "^13.0.0"
|
||||
"@angular/common": ">=14.0.0",
|
||||
"@angular/core": ">=14.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@vality/swag-claim-management": {
|
||||
@ -5002,18 +5002,6 @@
|
||||
"@angular/core": "^13.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@vality/swag-dark-api": {
|
||||
"version": "0.1.1-a3f1678.0",
|
||||
"resolved": "https://registry.npmjs.org/@vality/swag-dark-api/-/swag-dark-api-0.1.1-a3f1678.0.tgz",
|
||||
"integrity": "sha512-2mYcmHKn9YOWjoUU9h/7Pg/hUPUS8ODckjtzmFGNFwtQ2tStLtVkODBe56cthxcQHbnhrQs24Hekatyv9wi69w==",
|
||||
"dependencies": {
|
||||
"tslib": "^2.3.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@angular/common": "^13.0.0",
|
||||
"@angular/core": "^13.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@vality/swag-organizations": {
|
||||
"version": "1.0.1-cd6cc10.0",
|
||||
"resolved": "https://registry.npmjs.org/@vality/swag-organizations/-/swag-organizations-1.0.1-cd6cc10.0.tgz",
|
||||
@ -5039,9 +5027,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@vality/swag-questionary-aggr-proxy": {
|
||||
"version": "0.1.1-1dc5add.0",
|
||||
"resolved": "https://registry.npmjs.org/@vality/swag-questionary-aggr-proxy/-/swag-questionary-aggr-proxy-0.1.1-1dc5add.0.tgz",
|
||||
"integrity": "sha512-SHuDYPoqsfmHnqRtiwryxzSqvsllNSN9dvOLwUpGPN1lTsGWPDr/xsZDqgeJiTCnD/Tlf19repnWTtah1Mz/5Q==",
|
||||
"version": "0.1.1-ed41741.0",
|
||||
"resolved": "https://registry.npmjs.org/@vality/swag-questionary-aggr-proxy/-/swag-questionary-aggr-proxy-0.1.1-ed41741.0.tgz",
|
||||
"integrity": "sha512-Zm2DINHuG4xP+rmxWo2yvRHpkf84hNBS7giuE5AHw/zYPXiKG+9FiQxKYpU6g3OB4geZZWkt4lWLYgVwfcFFfQ==",
|
||||
"dependencies": {
|
||||
"tslib": "^2.3.0"
|
||||
},
|
||||
@ -5063,9 +5051,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@vality/swag-wallet": {
|
||||
"version": "0.1.1-9a236df.0",
|
||||
"resolved": "https://registry.npmjs.org/@vality/swag-wallet/-/swag-wallet-0.1.1-9a236df.0.tgz",
|
||||
"integrity": "sha512-equiIidtj1xblTFDk4z7Y4MsJxdlM2eaimMyWLHVYJrMkWPkQkYldC9V5bFWj5c16AY8d5zhXnOq6vaVBMp0ww==",
|
||||
"version": "0.1.2-21b69d2.0",
|
||||
"resolved": "https://registry.npmjs.org/@vality/swag-wallet/-/swag-wallet-0.1.2-21b69d2.0.tgz",
|
||||
"integrity": "sha512-zbyoiJ4ZJAvCtXpTRad5n7xwTwavl40UWLaU2DWSdp/cgjKd9yhUoEUU89+HLE6rZpqQL6fdSuqZ5CyFEfh9Yg==",
|
||||
"dependencies": {
|
||||
"tslib": "^2.3.0"
|
||||
},
|
||||
@ -7240,6 +7228,24 @@
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/cross-env": {
|
||||
"version": "7.0.3",
|
||||
"resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz",
|
||||
"integrity": "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"cross-spawn": "^7.0.1"
|
||||
},
|
||||
"bin": {
|
||||
"cross-env": "src/bin/cross-env.js",
|
||||
"cross-env-shell": "src/bin/cross-env-shell.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10.14",
|
||||
"npm": ">=6",
|
||||
"yarn": ">=1"
|
||||
}
|
||||
},
|
||||
"node_modules/cross-spawn": {
|
||||
"version": "7.0.3",
|
||||
"dev": true,
|
||||
@ -21284,9 +21290,9 @@
|
||||
}
|
||||
},
|
||||
"@vality/swag-anapi-v2": {
|
||||
"version": "2.0.1-0405be2.0",
|
||||
"resolved": "https://registry.npmjs.org/@vality/swag-anapi-v2/-/swag-anapi-v2-2.0.1-0405be2.0.tgz",
|
||||
"integrity": "sha512-YHSMYjTByWVTiTyO1U+I6Rfwm6N1KUz3F4rPiG4WJRcjVut73nvoo1A1xCp5KC38qhQ7li+uTpGQ/kx8VaL5oQ==",
|
||||
"version": "2.0.1-38f360b.0",
|
||||
"resolved": "https://registry.npmjs.org/@vality/swag-anapi-v2/-/swag-anapi-v2-2.0.1-38f360b.0.tgz",
|
||||
"integrity": "sha512-6RCpXFDvD+BlKsQxrA2pDH6B9fyzp+X69zapNpTgmTsxeS5acR7Jf9MS+a0kL2Rz/B9HS86jt+VYk3pvQco/PQ==",
|
||||
"requires": {
|
||||
"tslib": "^2.3.0"
|
||||
}
|
||||
@ -21297,14 +21303,6 @@
|
||||
"tslib": "^2.3.0"
|
||||
}
|
||||
},
|
||||
"@vality/swag-dark-api": {
|
||||
"version": "0.1.1-a3f1678.0",
|
||||
"resolved": "https://registry.npmjs.org/@vality/swag-dark-api/-/swag-dark-api-0.1.1-a3f1678.0.tgz",
|
||||
"integrity": "sha512-2mYcmHKn9YOWjoUU9h/7Pg/hUPUS8ODckjtzmFGNFwtQ2tStLtVkODBe56cthxcQHbnhrQs24Hekatyv9wi69w==",
|
||||
"requires": {
|
||||
"tslib": "^2.3.0"
|
||||
}
|
||||
},
|
||||
"@vality/swag-organizations": {
|
||||
"version": "1.0.1-cd6cc10.0",
|
||||
"resolved": "https://registry.npmjs.org/@vality/swag-organizations/-/swag-organizations-1.0.1-cd6cc10.0.tgz",
|
||||
@ -21322,9 +21320,9 @@
|
||||
}
|
||||
},
|
||||
"@vality/swag-questionary-aggr-proxy": {
|
||||
"version": "0.1.1-1dc5add.0",
|
||||
"resolved": "https://registry.npmjs.org/@vality/swag-questionary-aggr-proxy/-/swag-questionary-aggr-proxy-0.1.1-1dc5add.0.tgz",
|
||||
"integrity": "sha512-SHuDYPoqsfmHnqRtiwryxzSqvsllNSN9dvOLwUpGPN1lTsGWPDr/xsZDqgeJiTCnD/Tlf19repnWTtah1Mz/5Q==",
|
||||
"version": "0.1.1-ed41741.0",
|
||||
"resolved": "https://registry.npmjs.org/@vality/swag-questionary-aggr-proxy/-/swag-questionary-aggr-proxy-0.1.1-ed41741.0.tgz",
|
||||
"integrity": "sha512-Zm2DINHuG4xP+rmxWo2yvRHpkf84hNBS7giuE5AHw/zYPXiKG+9FiQxKYpU6g3OB4geZZWkt4lWLYgVwfcFFfQ==",
|
||||
"requires": {
|
||||
"tslib": "^2.3.0"
|
||||
}
|
||||
@ -21338,9 +21336,9 @@
|
||||
}
|
||||
},
|
||||
"@vality/swag-wallet": {
|
||||
"version": "0.1.1-9a236df.0",
|
||||
"resolved": "https://registry.npmjs.org/@vality/swag-wallet/-/swag-wallet-0.1.1-9a236df.0.tgz",
|
||||
"integrity": "sha512-equiIidtj1xblTFDk4z7Y4MsJxdlM2eaimMyWLHVYJrMkWPkQkYldC9V5bFWj5c16AY8d5zhXnOq6vaVBMp0ww==",
|
||||
"version": "0.1.2-21b69d2.0",
|
||||
"resolved": "https://registry.npmjs.org/@vality/swag-wallet/-/swag-wallet-0.1.2-21b69d2.0.tgz",
|
||||
"integrity": "sha512-zbyoiJ4ZJAvCtXpTRad5n7xwTwavl40UWLaU2DWSdp/cgjKd9yhUoEUU89+HLE6rZpqQL6fdSuqZ5CyFEfh9Yg==",
|
||||
"requires": {
|
||||
"tslib": "^2.3.0"
|
||||
}
|
||||
@ -22921,6 +22919,15 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"cross-env": {
|
||||
"version": "7.0.3",
|
||||
"resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz",
|
||||
"integrity": "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"cross-spawn": "^7.0.1"
|
||||
}
|
||||
},
|
||||
"cross-spawn": {
|
||||
"version": "7.0.3",
|
||||
"dev": true,
|
||||
|
14
package.json
14
package.json
@ -5,7 +5,7 @@
|
||||
"scripts": {
|
||||
"postinstall": "ngcc",
|
||||
"start": "ng serve --proxy-config proxy.conf.js --port 8000",
|
||||
"stage": "ng serve --proxy-config proxy.conf.js --port 8001 --configuration=stage",
|
||||
"stage": "cross-env NODE_ENV=stage ng serve --proxy-config proxy.conf.js --port 8001 --configuration=stage",
|
||||
"fix": "npm run lint-fix && npm run prettier-fix",
|
||||
"build": "ng build --extra-webpack-config webpack.extra.js && npm run transloco:optimize",
|
||||
"test": "ng test",
|
||||
@ -13,7 +13,7 @@
|
||||
"i18n:extract": "transloco-keys-manager extract",
|
||||
"i18n:check": "transloco-keys-manager find --emit-error-on-extra-keys",
|
||||
"coverage": "npx http-server -c-1 -o -p 9875 ./coverage",
|
||||
"lint-cmd": "eslint \"src/**/*.{ts,js,html}\" --max-warnings 1067",
|
||||
"lint-cmd": "eslint \"src/**/*.{ts,js,html}\" --max-warnings 1073",
|
||||
"lint": "npm run lint-cmd",
|
||||
"lint-fix": "npm run lint-cmd -- --fix",
|
||||
"lint-errors": "npm run lint-cmd -- --quiet",
|
||||
@ -49,14 +49,13 @@
|
||||
"@sentry/angular": "7.7.0",
|
||||
"@sentry/integrations": "7.7.0",
|
||||
"@sentry/tracing": "7.7.0",
|
||||
"@vality/swag-anapi-v2": "2.0.1-0405be2.0",
|
||||
"@vality/swag-anapi-v2": "2.0.1-38f360b.0",
|
||||
"@vality/swag-claim-management": "0.1.1-bfc2e6c.0",
|
||||
"@vality/swag-dark-api": "0.1.1-a3f1678.0",
|
||||
"@vality/swag-organizations": "1.0.1-cd6cc10.0",
|
||||
"@vality/swag-payments": "0.1.1-d71aebc.0",
|
||||
"@vality/swag-questionary-aggr-proxy": "0.1.1-1dc5add.0",
|
||||
"@vality/swag-questionary-aggr-proxy": "0.1.1-ed41741.0",
|
||||
"@vality/swag-url-shortener": "0.1.1-f780d07.0",
|
||||
"@vality/swag-wallet": "0.1.1-9a236df.0",
|
||||
"@vality/swag-wallet": "0.1.2-21b69d2.0",
|
||||
"angular-epic-spinners": "2.0.0",
|
||||
"angular-file": "^3.0.1",
|
||||
"angular2-text-mask": "^9.0.0",
|
||||
@ -103,6 +102,7 @@
|
||||
"@typescript-eslint/eslint-plugin": "5.31.0",
|
||||
"@typescript-eslint/parser": "5.31.0",
|
||||
"concurrently": "7.0.0",
|
||||
"cross-env": "^7.0.3",
|
||||
"dotenv": "^16.0.3",
|
||||
"eslint": "8.20.0",
|
||||
"eslint-config-prettier": "8.5.0",
|
||||
@ -127,4 +127,4 @@
|
||||
"ts-node": "10.9.1",
|
||||
"typescript": "4.7.4"
|
||||
}
|
||||
}
|
||||
}
|
@ -26,6 +26,9 @@ function createSubdomainByPathProxy(target, subdomainPathPrefix = '__') {
|
||||
secure: false,
|
||||
logLevel: 'debug',
|
||||
changeOrigin: true,
|
||||
onProxyReq: (req) => {
|
||||
req.setHeader('origin', `https://dashboard.${host}${port ? `:${port}` : ''}`);
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { TranslocoService } from '@ngneat/transloco';
|
||||
import { InvoiceStatus, Report, RefundStatus, PaymentSearchResult } from '@vality/swag-anapi-v2';
|
||||
import { BankCardPaymentSystem } from '@vality/swag-anapi-v2/lib/model/bankCardPaymentSystem';
|
||||
import { BankCardTokenProvider } from '@vality/swag-anapi-v2/lib/model/bankCardTokenProvider';
|
||||
|
||||
import { PaymentSystem, TokenProvider } from '@dsh/api/payments';
|
||||
|
||||
import { DictionaryService } from '../utils';
|
||||
|
||||
@ -73,7 +73,7 @@ export class AnapiDictionaryService {
|
||||
pending: this.t.translate('anapi.reportStatus.pending', null, 'dictionary'),
|
||||
}));
|
||||
|
||||
bankCardPaymentSystem$ = this.dictionaryService.create<BankCardPaymentSystem>(() => ({
|
||||
bankCardPaymentSystem$ = this.dictionaryService.create<PaymentSystem>(() => ({
|
||||
amex: this.t.translate('anapi.bankCardPaymentSystem.amex', null, 'dictionary'),
|
||||
dankort: this.t.translate('anapi.bankCardPaymentSystem.dankort', null, 'dictionary'),
|
||||
dinersclub: this.t.translate('anapi.bankCardPaymentSystem.dinersclub', null, 'dictionary'),
|
||||
@ -92,7 +92,7 @@ export class AnapiDictionaryService {
|
||||
uzcard: this.t.translate('anapi.bankCardPaymentSystem.uzcard', null, 'dictionary'),
|
||||
}));
|
||||
|
||||
bankCardTokenProvider$ = this.dictionaryService.create<BankCardTokenProvider>(() => ({
|
||||
bankCardTokenProvider$ = this.dictionaryService.create<TokenProvider>(() => ({
|
||||
applepay: this.t.translate('anapi.bankCardTokenProvider.applepay', null, 'dictionary'),
|
||||
googlepay: this.t.translate('anapi.bankCardTokenProvider.googlepay', null, 'dictionary'),
|
||||
samsungpay: this.t.translate('anapi.bankCardTokenProvider.samsungpay', null, 'dictionary'),
|
||||
|
@ -1,18 +0,0 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { TranslocoService } from '@ngneat/transloco';
|
||||
import { RefundStatus } from '@vality/swag-dark-api';
|
||||
|
||||
import { DictionaryService } from '../utils';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class DarkApiDictionaryService {
|
||||
refundStatus$ = this.dictionaryService.create<RefundStatus.StatusEnum>(() => ({
|
||||
pending: this.t.translate('darkApi.refundStatus.pending', null, 'dictionary'),
|
||||
succeeded: this.t.translate('darkApi.refundStatus.succeeded', null, 'dictionary'),
|
||||
failed: this.t.translate('darkApi.refundStatus.failed', null, 'dictionary'),
|
||||
}));
|
||||
|
||||
constructor(private t: TranslocoService, private dictionaryService: DictionaryService) {}
|
||||
}
|
@ -1,16 +0,0 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { Configuration } from '@vality/swag-dark-api';
|
||||
|
||||
import { ConfigService } from '../../config';
|
||||
|
||||
@NgModule({
|
||||
providers: [
|
||||
{
|
||||
provide: Configuration,
|
||||
deps: [ConfigService],
|
||||
useFactory: (configService: ConfigService) =>
|
||||
new Configuration({ basePath: `${configService.apiEndpoint}/dark-api/v1` }),
|
||||
},
|
||||
],
|
||||
})
|
||||
export class DarkApiModule {}
|
@ -1,53 +0,0 @@
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { Injectable, Injector } from '@angular/core';
|
||||
import { FilesService as ApiFilesService, FileUploadData } from '@vality/swag-dark-api';
|
||||
import { forkJoin, Observable, of } from 'rxjs';
|
||||
import { map, switchMap } from 'rxjs/operators';
|
||||
|
||||
import { createApi, ApiMethodParams } from '../utils';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class FilesService extends createApi(ApiFilesService) {
|
||||
constructor(injector: Injector, private http: HttpClient) {
|
||||
super(injector);
|
||||
}
|
||||
|
||||
uploadFiles(files: File[]) {
|
||||
return forkJoin(
|
||||
files.map((file) =>
|
||||
this.getUploadLink().pipe(
|
||||
switchMap((uploadData) =>
|
||||
forkJoin([of(uploadData.fileId), this.uploadFileToUrl(file, uploadData.url)])
|
||||
),
|
||||
map(([fileId]) => fileId)
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
getDecodedFileInfo = (params: ApiMethodParams<ApiFilesService['getFileInfo'], 'xRequestID'>) => {
|
||||
return this.getFileInfo(params).pipe(
|
||||
map((file) => ({
|
||||
...file,
|
||||
fileName: decodeURI(file.fileName),
|
||||
}))
|
||||
);
|
||||
};
|
||||
|
||||
private uploadFileToUrl(file: File, url: string): Observable<any> {
|
||||
return this.http.put(url, file, {
|
||||
headers: {
|
||||
/* eslint-disable @typescript-eslint/naming-convention */
|
||||
'Content-Disposition': `attachment;filename=${encodeURI(file.name)}`,
|
||||
'Content-Type': '',
|
||||
/* eslint-enable @typescript-eslint/naming-convention */
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
private getUploadLink(): Observable<FileUploadData> {
|
||||
return this.uploadFile({ uploadFileRequest: { metadata: {} } });
|
||||
}
|
||||
}
|
@ -1,2 +0,0 @@
|
||||
export * from './dark-api.module';
|
||||
export * from './files.service';
|
@ -1,9 +1,11 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { ContractsService as ApiContractsService } from '@vality/swag-payments';
|
||||
|
||||
import { PartyIdExtension } from '@dsh/api/utils/extensions';
|
||||
|
||||
import { createApi } from '../utils';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class ContractsService extends createApi(ApiContractsService) {}
|
||||
export class ContractsService extends createApi(ApiContractsService, [PartyIdExtension]) {}
|
||||
|
@ -1,9 +1,19 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Injectable, Injector } from '@angular/core';
|
||||
import { InvoiceTemplatesService as ApiInvoiceTemplatesService } from '@vality/swag-payments';
|
||||
|
||||
import { PartyIdPatchMethodService } from '@dsh/api/utils/extensions';
|
||||
|
||||
import { createApi } from '../utils';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class InvoiceTemplatesService extends createApi(ApiInvoiceTemplatesService) {}
|
||||
export class InvoiceTemplatesService extends createApi(ApiInvoiceTemplatesService) {
|
||||
constructor(injector: Injector, private partyIdPatchMethodService: PartyIdPatchMethodService) {
|
||||
super(injector);
|
||||
this.createInvoiceTemplate = this.partyIdPatchMethodService.patch(
|
||||
this.createInvoiceTemplate,
|
||||
(params, partyId) => (params.invoiceTemplateCreateParams.partyID = partyId)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1,9 +1,19 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Injectable, Injector } from '@angular/core';
|
||||
import { InvoicesService as ApiInvoicesService } from '@vality/swag-payments';
|
||||
|
||||
import { PartyIdPatchMethodService } from '@dsh/api/utils/extensions';
|
||||
|
||||
import { createApi } from '../utils';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class InvoicesService extends createApi(ApiInvoicesService) {}
|
||||
export class InvoicesService extends createApi(ApiInvoicesService) {
|
||||
constructor(injector: Injector, partyIdPatchMethodService: PartyIdPatchMethodService) {
|
||||
super(injector);
|
||||
this.createInvoice = partyIdPatchMethodService.patch(
|
||||
this.createInvoice,
|
||||
(p, id) => (p.invoiceParams.partyID = id)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1,9 +1,19 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Injectable, Injector } from '@angular/core';
|
||||
import { PayoutsService as ApiPayoutsService } from '@vality/swag-payments';
|
||||
|
||||
import { PartyIdExtension, PartyIdPatchMethodService } from '@dsh/api/utils/extensions';
|
||||
|
||||
import { createApi } from '../utils';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class PayoutsService extends createApi(ApiPayoutsService) {}
|
||||
export class PayoutsService extends createApi(ApiPayoutsService, [PartyIdExtension]) {
|
||||
constructor(injector: Injector, private partyIdPatchMethodService: PartyIdPatchMethodService) {
|
||||
super(injector);
|
||||
this.createPayout = partyIdPatchMethodService.patch(
|
||||
this.createPayout,
|
||||
(params, partyId) => (params.payoutParams.partyID = partyId)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1,32 +1,13 @@
|
||||
import { Injectable, Injector } from '@angular/core';
|
||||
import { ShopsService as ApiShopsService, Shop } from '@vality/swag-payments';
|
||||
import { defer, Observable, Subject, combineLatest } from 'rxjs';
|
||||
import { startWith, switchMap } from 'rxjs/operators';
|
||||
|
||||
import { ContextService } from '@dsh/app/shared';
|
||||
import { shareReplayRefCount } from '@dsh/operators';
|
||||
import { Injectable } from '@angular/core';
|
||||
import { ShopsService as ApiShopsService } from '@vality/swag-payments';
|
||||
|
||||
import { createApi } from '../utils';
|
||||
import { PartyIdExtension } from '../utils/extensions';
|
||||
|
||||
/**
|
||||
* Use only "SomeForParty" methods
|
||||
*/
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class ShopsService extends createApi(ApiShopsService) {
|
||||
shops$: Observable<Shop[]> = combineLatest([
|
||||
this.contextService.organization$,
|
||||
defer(() => this.reloadShops$).pipe(startWith(null)),
|
||||
]).pipe(
|
||||
switchMap(([{ party }]) => this.getShopsForParty({ partyID: party })),
|
||||
shareReplayRefCount()
|
||||
);
|
||||
|
||||
private reloadShops$ = new Subject<void>();
|
||||
|
||||
constructor(injector: Injector, private contextService: ContextService) {
|
||||
super(injector);
|
||||
}
|
||||
|
||||
reloadShops(): void {
|
||||
this.reloadShops$.next();
|
||||
}
|
||||
}
|
||||
export class ShopsService extends createApi(ApiShopsService, [PartyIdExtension]) {}
|
||||
|
@ -1,9 +1,19 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Injectable, Injector } from '@angular/core';
|
||||
import { WebhooksService as ApiWebhooksService } from '@vality/swag-payments';
|
||||
|
||||
import { PartyIdPatchMethodService } from '@dsh/api/utils/extensions';
|
||||
|
||||
import { createApi } from '../utils';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class WebhooksService extends createApi(ApiWebhooksService) {}
|
||||
export class WebhooksService extends createApi(ApiWebhooksService) {
|
||||
constructor(injector: Injector, partyIdPatchMethodService: PartyIdPatchMethodService) {
|
||||
super(injector);
|
||||
this.createWebhook = partyIdPatchMethodService.patch(
|
||||
this.createWebhook,
|
||||
(params, partyID) => (params.webhookParams.partyID = partyID)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1 +1,2 @@
|
||||
export * from './party-id-extension';
|
||||
export * from './party-id-patch-method.service';
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { first, map } from 'rxjs/operators';
|
||||
|
||||
import { ContextService } from '@dsh/app/shared';
|
||||
import { ContextOrganizationService } from '@dsh/app/shared/services/context-organization';
|
||||
|
||||
import { ApiExtension } from '../create-api';
|
||||
|
||||
@ -9,10 +9,10 @@ import { ApiExtension } from '../create-api';
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class PartyIdExtension implements ApiExtension {
|
||||
constructor(private contextService: ContextService) {}
|
||||
constructor(private contextOrganizationService: ContextOrganizationService) {}
|
||||
|
||||
selector() {
|
||||
return this.contextService.organization$.pipe(
|
||||
return this.contextOrganizationService.organization$.pipe(
|
||||
first(),
|
||||
map(({ party }) => ({ partyID: party }))
|
||||
);
|
||||
|
@ -0,0 +1,25 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import cloneDeep from 'lodash-es/cloneDeep';
|
||||
import { Observable, switchMap } from 'rxjs';
|
||||
import { DeepPartial } from 'utility-types';
|
||||
|
||||
import { PartyIdExtension } from './party-id-extension';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class PartyIdPatchMethodService extends PartyIdExtension {
|
||||
patch<P extends object, R, E extends DeepPartial<P> | void>(
|
||||
method: (params: P) => Observable<R>,
|
||||
patch: (params: P, partyId: string) => unknown
|
||||
): (params: E) => Observable<R> {
|
||||
return (params) =>
|
||||
this.selector().pipe(
|
||||
switchMap(({ partyID }) => {
|
||||
const newParams = cloneDeep(params);
|
||||
patch(newParams as P, partyID);
|
||||
return method(newParams as P);
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { IdentitiesService as ApiIdentitiesService } from '@vality/swag-wallet';
|
||||
import { Subject, defer } from 'rxjs';
|
||||
import { switchMapTo, pluck, startWith } from 'rxjs/operators';
|
||||
import { IdentitiesService as ApiIdentitiesService, Identity } from '@vality/swag-wallet';
|
||||
import { Subject, defer, switchMap } from 'rxjs';
|
||||
import { startWith, map } from 'rxjs/operators';
|
||||
|
||||
import { shareReplayRefCount } from '@dsh/operators';
|
||||
|
||||
@ -13,8 +13,8 @@ import { createApi } from '../utils';
|
||||
export class IdentitiesService extends createApi(ApiIdentitiesService) {
|
||||
identities$ = defer(() => this.reloadIdentities$).pipe(
|
||||
startWith<void>(undefined),
|
||||
switchMapTo(this.listIdentities()),
|
||||
pluck('result'),
|
||||
switchMap(() => this.listIdentities()),
|
||||
map((r) => r.result as Identity[]),
|
||||
shareReplayRefCount()
|
||||
);
|
||||
|
||||
|
@ -1,10 +1,6 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { TranslocoService } from '@ngneat/transloco';
|
||||
import { DepositRevert } from '@vality/swag-wallet';
|
||||
import { Deposit } from '@vality/swag-wallet/lib/model/deposit';
|
||||
import { DestinationsTopic } from '@vality/swag-wallet/lib/model/destinationsTopic';
|
||||
import { Withdrawal } from '@vality/swag-wallet/lib/model/withdrawal';
|
||||
import { WithdrawalsTopic } from '@vality/swag-wallet/lib/model/withdrawalsTopic';
|
||||
import { DepositRevert, WithdrawalsTopic, DestinationsTopic, Deposit, Withdrawal } from '@vality/swag-wallet';
|
||||
|
||||
import { DictionaryService } from '../utils';
|
||||
|
||||
|
@ -1,3 +1,8 @@
|
||||
<dsh-home>
|
||||
<dsh-sections *ngIf="bootstrapped$ | async"></dsh-sections>
|
||||
<dsh-sections *ngIf="bootstrapped$ | async; else spinner"></dsh-sections>
|
||||
<ng-template #spinner>
|
||||
<div fxLayout="row" fxFlexAlign="center">
|
||||
<dsh-spinner style="margin: auto"></dsh-spinner>
|
||||
</div>
|
||||
</ng-template>
|
||||
</dsh-home>
|
||||
|
@ -1,13 +1,10 @@
|
||||
import { Component, Inject, OnInit } from '@angular/core';
|
||||
import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy';
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import * as Sentry from '@sentry/angular';
|
||||
import { first, map } from 'rxjs/operators';
|
||||
import { first } from 'rxjs/operators';
|
||||
|
||||
import { ENV, Env } from '../environments';
|
||||
import { BootstrapService } from './bootstrap.service';
|
||||
import { ContextService } from './shared';
|
||||
import { ContextOrganizationService } from './shared';
|
||||
|
||||
@UntilDestroy()
|
||||
@Component({
|
||||
selector: 'dsh-root',
|
||||
templateUrl: 'app.component.html',
|
||||
@ -18,15 +15,12 @@ export class AppComponent implements OnInit {
|
||||
|
||||
constructor(
|
||||
private bootstrapService: BootstrapService,
|
||||
@Inject(ENV) public env: Env,
|
||||
private contextService: ContextService
|
||||
private contextOrganizationService: ContextOrganizationService
|
||||
) {}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.bootstrapService.bootstrap();
|
||||
this.contextService.organization$
|
||||
.pipe(map(({ party }) => party))
|
||||
.pipe(first(), untilDestroyed(this))
|
||||
.subscribe((partyID) => Sentry.setUser({ id: partyID }));
|
||||
this.contextOrganizationService.organization$
|
||||
.pipe(first())
|
||||
.subscribe(({ party }) => Sentry.setUser({ id: party }));
|
||||
}
|
||||
}
|
||||
|
@ -18,7 +18,6 @@ import * as Sentry from '@sentry/angular';
|
||||
|
||||
import { AnapiModule } from '@dsh/api/anapi';
|
||||
import { ClaimManagementModule } from '@dsh/api/claim-management';
|
||||
import { DarkApiModule } from '@dsh/api/dark-api';
|
||||
import { PaymentsModule } from '@dsh/api/payments';
|
||||
import { QuestionaryAggrProxyModule } from '@dsh/api/questionary-aggr-proxy';
|
||||
import { UrlShortenerModule } from '@dsh/api/url-shortener';
|
||||
@ -26,6 +25,7 @@ import { WalletModule } from '@dsh/api/wallet';
|
||||
import { ErrorModule } from '@dsh/app/shared/services';
|
||||
import { QUERY_PARAMS_SERIALIZERS } from '@dsh/app/shared/services/query-params/utils/query-params-serializers';
|
||||
import { createDateRangeWithPresetSerializer } from '@dsh/components/date-range-filter';
|
||||
import { SpinnerModule } from '@dsh/components/indicators';
|
||||
|
||||
import { ENV, environment } from '../environments';
|
||||
import { OrganizationsModule } from './api/organizations';
|
||||
@ -64,8 +64,8 @@ import { TranslocoHttpLoaderService } from './transloco-http-loader.service';
|
||||
OrganizationsModule,
|
||||
UrlShortenerModule,
|
||||
QuestionaryAggrProxyModule,
|
||||
DarkApiModule,
|
||||
WalletModule,
|
||||
SpinnerModule,
|
||||
],
|
||||
providers: [
|
||||
LanguageService,
|
||||
|
@ -1,8 +1,8 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Observable, of } from 'rxjs';
|
||||
import { first, map } from 'rxjs/operators';
|
||||
import { map } from 'rxjs/operators';
|
||||
|
||||
import { ContextService } from '@dsh/app/shared';
|
||||
import { ContextOrganizationService } from '@dsh/app/shared';
|
||||
|
||||
import { ROLE_ACCESS_GROUPS } from './role-access-groups';
|
||||
import { RoleAccess } from './types/role-access';
|
||||
@ -16,12 +16,11 @@ const ROLE_ACCESSES_OBJECT = Object.fromEntries(
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class RoleAccessService {
|
||||
constructor(private contextService: ContextService) {}
|
||||
constructor(private contextOrganizationService: ContextOrganizationService) {}
|
||||
|
||||
isAccessAllowed(roleAccessNames: RoleAccessName[], type: 'every' | 'some' = 'every'): Observable<boolean> {
|
||||
if (!roleAccessNames.length) return of(true);
|
||||
return this.contextService.member$.pipe(
|
||||
first(),
|
||||
return this.contextOrganizationService.member$.pipe(
|
||||
map((member) => {
|
||||
const memberRoles = member.roles.map((r) => r.roleId);
|
||||
return roleAccessNames[type]((access) =>
|
||||
|
@ -1,87 +1,26 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { TranslocoService } from '@ngneat/transloco';
|
||||
import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy';
|
||||
import { Organization } from '@vality/swag-organizations';
|
||||
import { concat, defer, Observable, of, ReplaySubject, throwError } from 'rxjs';
|
||||
import { catchError, first, mapTo, shareReplay, switchMap, takeLast, tap, map } from 'rxjs/operators';
|
||||
import { Observable, throwError, switchMap } from 'rxjs';
|
||||
import { map, catchError, tap } from 'rxjs/operators';
|
||||
|
||||
import { ClaimsService, createTestShopClaimChangeset } from '@dsh/api/claim-management';
|
||||
import { DEFAULT_ORGANIZATION_NAME, OrgsService } from '@dsh/api/organizations';
|
||||
import { ShopsService } from '@dsh/api/payments';
|
||||
import { CommonError, ErrorService, IdGeneratorService } from '@dsh/app/shared';
|
||||
import { ShopsDataService, ErrorService, CommonError } from '@dsh/app/shared';
|
||||
|
||||
@UntilDestroy()
|
||||
@Injectable()
|
||||
export class BootstrapService {
|
||||
bootstrapped$: Observable<boolean> = defer(() => this.bootstrap$).pipe(
|
||||
switchMap(() => this.getBootstrapped()),
|
||||
untilDestroyed(this),
|
||||
shareReplay(1)
|
||||
bootstrapped$: Observable<boolean> = this.shopsDataService.shops$.pipe(
|
||||
catchError((err) =>
|
||||
this.transloco.selectTranslate<string>('app.errors.bootstrapAppFailed', null, 'components').pipe(
|
||||
tap((msg) => this.errorService.error(new CommonError(msg))),
|
||||
switchMap(() => throwError(err))
|
||||
)
|
||||
),
|
||||
|
||||
map(() => true)
|
||||
);
|
||||
|
||||
private bootstrap$ = new ReplaySubject<void>(1);
|
||||
|
||||
constructor(
|
||||
private shopService: ShopsService,
|
||||
private claimsService: ClaimsService,
|
||||
private errorService: ErrorService,
|
||||
private organizationsService: OrgsService,
|
||||
private shopsDataService: ShopsDataService,
|
||||
private transloco: TranslocoService,
|
||||
private idGenerator: IdGeneratorService
|
||||
private errorService: ErrorService
|
||||
) {}
|
||||
|
||||
bootstrap(): void {
|
||||
this.bootstrap$.next();
|
||||
}
|
||||
|
||||
private getBootstrapped(): Observable<boolean> {
|
||||
return concat(this.initOrganization(), this.initShop()).pipe(
|
||||
takeLast(1),
|
||||
catchError((err) =>
|
||||
this.transloco.selectTranslate<string>('app.errors.bootstrapAppFailed', null, 'components').pipe(
|
||||
tap((msg) => this.errorService.error(new CommonError(msg))),
|
||||
switchMap(() => throwError(err))
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
private initOrganization(): Observable<boolean> {
|
||||
return this.organizationsService.listOrgMembership({ limit: 1 }).pipe(
|
||||
first(),
|
||||
switchMap((orgs) => (orgs.result.length ? of(true) : this.createOrganization())),
|
||||
catchError((err) => {
|
||||
this.errorService.error(err, false);
|
||||
return of(true);
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
private createOrganization(): Observable<boolean> {
|
||||
return this.organizationsService
|
||||
.createOrg({ organization: { name: DEFAULT_ORGANIZATION_NAME } as Organization })
|
||||
.pipe(mapTo(true));
|
||||
}
|
||||
|
||||
private initShop(): Observable<boolean> {
|
||||
return this.shopService.shops$.pipe(
|
||||
first(),
|
||||
switchMap((shops) =>
|
||||
shops.length ? of(true) : this.createTestShop().pipe(tap(() => this.shopService.reloadShops()))
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
private createTestShop(): Observable<boolean> {
|
||||
return this.claimsService
|
||||
.createClaim({
|
||||
changeset: createTestShopClaimChangeset(
|
||||
this.idGenerator.uuid(),
|
||||
this.idGenerator.uuid(),
|
||||
this.idGenerator.uuid(),
|
||||
this.idGenerator.uuid()
|
||||
),
|
||||
})
|
||||
.pipe(map(() => true));
|
||||
}
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ import { first, map } from 'rxjs/operators';
|
||||
|
||||
import { SEARCH_LIMIT } from '@dsh/app/sections/tokens';
|
||||
import { BaseDialogResponseStatus } from '@dsh/app/shared/components/dialog/base-dialog';
|
||||
import { ContextService } from '@dsh/app/shared/services/context';
|
||||
import { ContextOrganizationService } from '@dsh/app/shared/services';
|
||||
import { FetchOrganizationsService } from '@dsh/app/shared/services/fetch-organizations';
|
||||
|
||||
const DISPLAYED_COUNT = 5;
|
||||
@ -25,7 +25,7 @@ export class SelectActiveOrganizationDialogComponent implements OnInit {
|
||||
hasMore$ = this.fetchOrganizationsService.hasMore$;
|
||||
selectedOrganization: Organization;
|
||||
isLoading$ = this.fetchOrganizationsService.doAction$;
|
||||
contextOrganization$ = this.contextService.organization$;
|
||||
contextOrganization$ = this.contextOrganizationService.organization$;
|
||||
|
||||
constructor(
|
||||
private dialogRef: MatDialogRef<
|
||||
@ -34,12 +34,12 @@ export class SelectActiveOrganizationDialogComponent implements OnInit {
|
||||
>,
|
||||
private fetchOrganizationsService: FetchOrganizationsService,
|
||||
private router: Router,
|
||||
private contextService: ContextService
|
||||
private contextOrganizationService: ContextOrganizationService
|
||||
) {}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.fetchOrganizationsService.search();
|
||||
combineLatest([this.organizations$, this.contextService.organization$])
|
||||
combineLatest([this.organizations$, this.contextOrganizationService.organization$])
|
||||
.pipe(
|
||||
first(),
|
||||
map(([orgs, activeOrg]) => orgs.find((org) => org.id === activeOrg.id)),
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { ChangeDetectionStrategy, Component, Input } from '@angular/core';
|
||||
import { map } from 'rxjs/operators';
|
||||
|
||||
import { ContextService } from '@dsh/app/shared/services/context';
|
||||
import { ContextOrganizationService } from '@dsh/app/shared/services';
|
||||
import { coerceBoolean } from '@dsh/utils';
|
||||
|
||||
import { KeycloakService } from '../../../../auth';
|
||||
@ -18,7 +18,10 @@ export class UserDropdownComponent {
|
||||
@Input() @coerceBoolean expanded = false;
|
||||
|
||||
username = this.keycloakService.getUsername();
|
||||
orgName$ = this.contextService.organization$.pipe(map(({ name }) => name));
|
||||
orgName$ = this.contextOrganizationService.organization$.pipe(map(({ name }) => name));
|
||||
|
||||
constructor(private contextService: ContextService, private keycloakService: KeycloakService) {}
|
||||
constructor(
|
||||
private contextOrganizationService: ContextOrganizationService,
|
||||
private keycloakService: KeycloakService
|
||||
) {}
|
||||
}
|
||||
|
@ -6,7 +6,7 @@ import { Organization } from '@vality/swag-organizations';
|
||||
import { map, filter } from 'rxjs/operators';
|
||||
|
||||
import { DIALOG_CONFIG, DialogConfig } from '@dsh/app/sections/tokens';
|
||||
import { ContextService } from '@dsh/app/shared';
|
||||
import { ContextOrganizationService } from '@dsh/app/shared';
|
||||
import { BaseDialogResponseStatus } from '@dsh/app/shared/components/dialog/base-dialog';
|
||||
|
||||
import { KeycloakService } from '../../../../auth';
|
||||
@ -22,7 +22,7 @@ export class UserComponent {
|
||||
@Output() selected = new EventEmitter<void>();
|
||||
|
||||
username = this.keycloakService.getUsername();
|
||||
activeOrg$ = this.contextService.organization$;
|
||||
activeOrg$ = this.contextOrganizationService.organization$;
|
||||
keycloakAccountEndpoint = `${this.config.keycloakEndpoint}/auth/realms/external/account/`;
|
||||
userLinksConfig$ = this.transloco.selectTranslation('components').pipe(
|
||||
map(() => [
|
||||
@ -44,7 +44,7 @@ export class UserComponent {
|
||||
constructor(
|
||||
private keycloakService: KeycloakService,
|
||||
private config: ConfigService,
|
||||
private contextService: ContextService,
|
||||
private contextOrganizationService: ContextOrganizationService,
|
||||
private router: Router,
|
||||
private dialog: MatDialog,
|
||||
private transloco: TranslocoService,
|
||||
@ -69,7 +69,7 @@ export class UserComponent {
|
||||
.afterClosed()
|
||||
.pipe(filter((res) => !Object.values(BaseDialogResponseStatus).includes(res as BaseDialogResponseStatus)))
|
||||
.subscribe((org: Organization) => {
|
||||
this.contextService.switchOrganization(org.id);
|
||||
this.contextOrganizationService.switchOrganization(org.id);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -7,8 +7,8 @@ import { BehaviorSubject, combineLatest, EMPTY, Observable, of } from 'rxjs';
|
||||
import { first, map, switchMap, tap } from 'rxjs/operators';
|
||||
|
||||
import { OrganizationsDictionaryService } from '@dsh/api/organizations';
|
||||
import { ShopsService } from '@dsh/api/payments';
|
||||
import { DialogConfig, DIALOG_CONFIG } from '@dsh/app/sections/tokens';
|
||||
import { ShopsDataService } from '@dsh/app/shared';
|
||||
import { sortRoleIds } from '@dsh/app/shared/components/organization-roles/utils/sort-role-ids';
|
||||
import { PartialReadonly } from '@dsh/type-utils';
|
||||
import { coerceBoolean } from '@dsh/utils';
|
||||
@ -49,7 +49,7 @@ export class ChangeRolesTableComponent implements OnInit {
|
||||
@Output() removedRoles = new EventEmitter<PartialReadonly<MemberRole>[]>();
|
||||
|
||||
roleIds: RoleId[] = [];
|
||||
shops$ = this.shopsService.shops$;
|
||||
shops$ = this.shopsDataService.shops$;
|
||||
roleIdDict$ = this.organizationsDictionaryService.roleId$;
|
||||
|
||||
get availableRoles(): RoleId[] {
|
||||
@ -71,7 +71,7 @@ export class ChangeRolesTableComponent implements OnInit {
|
||||
}
|
||||
|
||||
constructor(
|
||||
private shopsService: ShopsService,
|
||||
private shopsDataService: ShopsDataService,
|
||||
private dialog: MatDialog,
|
||||
@Inject(DIALOG_CONFIG) private dialogConfig: DialogConfig,
|
||||
private cdr: ChangeDetectorRef,
|
||||
|
@ -7,7 +7,7 @@ import { filter, pluck, switchMap } from 'rxjs/operators';
|
||||
|
||||
import { OrgsService } from '@dsh/api/organizations';
|
||||
import { BaseDialogResponseStatus } from '@dsh/app/shared/components/dialog/base-dialog';
|
||||
import { ErrorService, NotificationService, ContextService } from '@dsh/app/shared/services';
|
||||
import { ErrorService, NotificationService, ContextOrganizationService } from '@dsh/app/shared/services';
|
||||
import { FetchOrganizationsService } from '@dsh/app/shared/services/fetch-organizations';
|
||||
import { OrganizationManagementService } from '@dsh/app/shared/services/organization-management/organization-management.service';
|
||||
import { ConfirmActionDialogComponent, ConfirmActionDialogResult } from '@dsh/components/popups';
|
||||
@ -29,7 +29,7 @@ export class OrganizationComponent implements OnChanges {
|
||||
|
||||
@Output() changed = new EventEmitter<void>();
|
||||
|
||||
member$ = this.contextService.member$;
|
||||
member$ = this.contextOrganizationService.member$;
|
||||
membersCount$ = this.organizationManagementService.members$.pipe(pluck('length'));
|
||||
hasAdminAccess$ = this.organizationManagementService.hasAdminAccess$;
|
||||
isOwner$ = this.organizationManagementService.isOrganizationOwner$;
|
||||
@ -41,7 +41,7 @@ export class OrganizationComponent implements OnChanges {
|
||||
private notificationService: NotificationService,
|
||||
private errorService: ErrorService,
|
||||
private fetchOrganizationsService: FetchOrganizationsService,
|
||||
private contextService: ContextService
|
||||
private contextOrganizationService: ContextOrganizationService
|
||||
) {}
|
||||
|
||||
ngOnChanges({ organization }: ComponentChanges<OrganizationComponent>) {
|
||||
|
@ -4,7 +4,7 @@ import { ActivatedRoute } from '@angular/router';
|
||||
import { FormControl } from '@ngneat/reactive-forms';
|
||||
import { pluck, shareReplay } from 'rxjs/operators';
|
||||
|
||||
import { ShopsService } from '@dsh/api/payments';
|
||||
import { ShopsDataService } from '@dsh/app/shared';
|
||||
import { FormData } from '@dsh/app/shared/components/create-invoice-form';
|
||||
import { SHARE_REPLAY_CONF } from '@dsh/operators';
|
||||
|
||||
@ -17,9 +17,13 @@ export class CreateInvoiceOrInvoiceTemplateService {
|
||||
|
||||
shops$ = this.route.params.pipe(
|
||||
pluck('realm'),
|
||||
filterShopsByRealm(this.shopService.shops$),
|
||||
filterShopsByRealm(this.shopsDataService.shops$),
|
||||
shareReplay(SHARE_REPLAY_CONF)
|
||||
);
|
||||
|
||||
constructor(private fb: UntypedFormBuilder, private route: ActivatedRoute, private shopService: ShopsService) {}
|
||||
constructor(
|
||||
private fb: UntypedFormBuilder,
|
||||
private route: ActivatedRoute,
|
||||
private shopsDataService: ShopsDataService
|
||||
) {}
|
||||
}
|
||||
|
@ -4,7 +4,8 @@ import { WebhookScope } from '@vality/swag-payments';
|
||||
import { BehaviorSubject, combineLatest } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
|
||||
import { ShopsService, PaymentsDictionaryService } from '@dsh/api/payments';
|
||||
import { PaymentsDictionaryService } from '@dsh/api/payments';
|
||||
import { ShopsDataService } from '@dsh/app/shared';
|
||||
import { oneMustBeSelected } from '@dsh/components/form-controls';
|
||||
|
||||
import { getEventsByTopic } from '../get-events-by-topic';
|
||||
@ -19,7 +20,7 @@ export class CreateWebhookFormComponent implements OnInit {
|
||||
@Input()
|
||||
form: UntypedFormGroup;
|
||||
|
||||
shops$ = this.shopService.shops$;
|
||||
shops$ = this.shopsDataService.shops$;
|
||||
|
||||
activeTopic$ = new BehaviorSubject<TopicEnum>('InvoicesTopic');
|
||||
|
||||
@ -29,7 +30,7 @@ export class CreateWebhookFormComponent implements OnInit {
|
||||
]).pipe(map(([i, c]) => ({ ...i, ...c })));
|
||||
|
||||
constructor(
|
||||
private shopService: ShopsService,
|
||||
private shopsDataService: ShopsDataService,
|
||||
private fb: UntypedFormBuilder,
|
||||
private paymentsDictionaryService: PaymentsDictionaryService
|
||||
) {}
|
||||
|
@ -6,7 +6,7 @@ import { PaymentInstitution, Shop } from '@vality/swag-payments';
|
||||
import { Observable, of, ReplaySubject } from 'rxjs';
|
||||
import { filter, pluck, switchMap, take } from 'rxjs/operators';
|
||||
|
||||
import { ShopsService } from '@dsh/api/payments';
|
||||
import { ShopsDataService } from '@dsh/app/shared';
|
||||
|
||||
import { filterShopsByRealm } from '../../operators';
|
||||
import { CreateInvoiceDialogComponent } from './components/create-invoice-dialog/create-invoice-dialog.component';
|
||||
@ -16,7 +16,7 @@ import RealmEnum = PaymentInstitution.RealmEnum;
|
||||
@Injectable()
|
||||
export class CreateInvoiceService {
|
||||
constructor(
|
||||
private apiShopsService: ShopsService,
|
||||
private shopsDataService: ShopsDataService,
|
||||
private dialog: MatDialog,
|
||||
private transloco: TranslocoService,
|
||||
private snackBar: MatSnackBar
|
||||
@ -26,7 +26,7 @@ export class CreateInvoiceService {
|
||||
const invoiceCreated$ = new ReplaySubject<string>(1);
|
||||
of(realm)
|
||||
.pipe(
|
||||
filterShopsByRealm(this.apiShopsService.shops$),
|
||||
filterShopsByRealm(this.shopsDataService.shops$),
|
||||
switchMap((shops) =>
|
||||
this.dialog
|
||||
.open<CreateInvoiceDialogComponent, Shop[]>(CreateInvoiceDialogComponent, {
|
||||
|
@ -2,7 +2,7 @@ import { Component, Injector, ChangeDetectionStrategy } from '@angular/core';
|
||||
import { FormBuilder } from '@ngneat/reactive-forms';
|
||||
import { WrappedFormControlSuperclass, provideValueAccessor } from '@s-libs/ng-core';
|
||||
|
||||
import { ShopsService } from '@dsh/api/payments';
|
||||
import { ShopsDataService } from '@dsh/app/shared';
|
||||
|
||||
@Component({
|
||||
selector: 'dsh-shops-filter',
|
||||
@ -11,9 +11,9 @@ import { ShopsService } from '@dsh/api/payments';
|
||||
providers: [provideValueAccessor(ShopsFilterComponent)],
|
||||
})
|
||||
export class ShopsFilterComponent extends WrappedFormControlSuperclass<string[]> {
|
||||
shops$ = this.shopsService.shops$;
|
||||
shops$ = this.shopsDataService.shops$;
|
||||
|
||||
constructor(injector: Injector, private fb: FormBuilder, private shopsService: ShopsService) {
|
||||
constructor(injector: Injector, private fb: FormBuilder, private shopsDataService: ShopsDataService) {
|
||||
super(injector);
|
||||
}
|
||||
}
|
||||
|
@ -12,7 +12,7 @@ import pick from 'lodash-es/pick';
|
||||
import { defer, ReplaySubject, BehaviorSubject, combineLatest } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
|
||||
import { ShopsService } from '@dsh/api/payments';
|
||||
import { ShopsDataService } from '@dsh/app/shared';
|
||||
import { createDateRangeWithPreset, Preset, DateRangeWithPreset } from '@dsh/components/date-range-filter';
|
||||
import { shareReplayRefCount } from '@dsh/operators';
|
||||
import { ComponentChanges } from '@dsh/type-utils';
|
||||
@ -49,7 +49,7 @@ export class InvoicesSearchFiltersComponent implements OnChanges, OnInit {
|
||||
shopIDs: null,
|
||||
invoiceStatus: null,
|
||||
});
|
||||
shops$ = defer(() => this.realm$).pipe(filterShopsByRealm(this.shopService.shops$), shareReplayRefCount());
|
||||
shops$ = defer(() => this.realm$).pipe(filterShopsByRealm(this.shopsDataService.shops$), shareReplayRefCount());
|
||||
isAdditionalFilterApplied$ = defer(() => this.additionalFilters$).pipe(map(negate(isEmpty)));
|
||||
|
||||
get keys(): string[] {
|
||||
@ -61,7 +61,7 @@ export class InvoicesSearchFiltersComponent implements OnChanges, OnInit {
|
||||
|
||||
constructor(
|
||||
private fb: FormBuilder,
|
||||
private shopService: ShopsService,
|
||||
private shopsDataService: ShopsDataService,
|
||||
private dialog: MatDialog,
|
||||
private mediaObserver: MediaObserver
|
||||
) {}
|
||||
|
@ -1,8 +1,9 @@
|
||||
import { Component, Injector } from '@angular/core';
|
||||
import { provideValueAccessor, WrappedFormControlSuperclass } from '@s-libs/ng-core';
|
||||
import { BankCardPaymentSystem } from '@vality/swag-anapi-v2';
|
||||
import { SearchPaymentsRequestParams } from '@vality/swag-anapi-v2';
|
||||
|
||||
import { AnapiDictionaryService } from '@dsh/api/anapi';
|
||||
import { PaymentSystem } from '@dsh/api/payments';
|
||||
|
||||
@Component({
|
||||
selector: 'dsh-payment-system-filter',
|
||||
@ -10,8 +11,10 @@ import { AnapiDictionaryService } from '@dsh/api/anapi';
|
||||
styleUrls: ['./payment-system-filter.component.scss'],
|
||||
providers: [provideValueAccessor(PaymentSystemFilterComponent)],
|
||||
})
|
||||
export class PaymentSystemFilterComponent extends WrappedFormControlSuperclass<BankCardPaymentSystem> {
|
||||
paymentSystems = Object.values(BankCardPaymentSystem);
|
||||
export class PaymentSystemFilterComponent extends WrappedFormControlSuperclass<
|
||||
SearchPaymentsRequestParams['bankCardPaymentSystem']
|
||||
> {
|
||||
paymentSystems = Object.values(PaymentSystem);
|
||||
bankCardPaymentSystemDict$ = this.anapiDictionaryService.bankCardPaymentSystem$;
|
||||
|
||||
constructor(injector: Injector, private anapiDictionaryService: AnapiDictionaryService) {
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { Component, Injector, ChangeDetectionStrategy } from '@angular/core';
|
||||
import { FormBuilder } from '@ngneat/reactive-forms';
|
||||
|
||||
import { ShopsService } from '@dsh/api/payments';
|
||||
import { ShopsDataService } from '@dsh/app/shared';
|
||||
import { ValidatedControlSuperclass, createControlProviders } from '@dsh/utils';
|
||||
|
||||
import { ShopsFilterForm } from './types';
|
||||
@ -17,9 +17,9 @@ export class ShopsFilterComponent extends ValidatedControlSuperclass<ShopsFilter
|
||||
shopIDs: null,
|
||||
});
|
||||
|
||||
shops$ = this.shopsService.shops$;
|
||||
shops$ = this.shopsDataService.shops$;
|
||||
|
||||
constructor(injector: Injector, private fb: FormBuilder, private shopsService: ShopsService) {
|
||||
constructor(injector: Injector, private fb: FormBuilder, private shopsDataService: ShopsDataService) {
|
||||
super(injector);
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,9 @@
|
||||
import { Component, Injector } from '@angular/core';
|
||||
import { provideValueAccessor, WrappedFormControlSuperclass } from '@s-libs/ng-core';
|
||||
import { BankCardTokenProvider } from '@vality/swag-anapi-v2';
|
||||
import { SearchPaymentsRequestParams } from '@vality/swag-anapi-v2';
|
||||
|
||||
import { AnapiDictionaryService } from '@dsh/api/anapi';
|
||||
import { TokenProvider } from '@dsh/api/payments';
|
||||
|
||||
@Component({
|
||||
selector: 'dsh-token-provider-filter',
|
||||
@ -10,8 +11,10 @@ import { AnapiDictionaryService } from '@dsh/api/anapi';
|
||||
styleUrls: ['./token-provider-filter.component.scss'],
|
||||
providers: [provideValueAccessor(TokenProviderFilterComponent)],
|
||||
})
|
||||
export class TokenProviderFilterComponent extends WrappedFormControlSuperclass<BankCardTokenProvider> {
|
||||
providers = Object.values(BankCardTokenProvider);
|
||||
export class TokenProviderFilterComponent extends WrappedFormControlSuperclass<
|
||||
SearchPaymentsRequestParams['bankCardTokenProvider']
|
||||
> {
|
||||
providers: TokenProvider[] = Object.values(TokenProvider);
|
||||
bankCardTokenProviderDict$ = this.anapiDictionaryService.bankCardTokenProvider$;
|
||||
|
||||
constructor(injector: Injector, private anapiDictionaryService: AnapiDictionaryService) {
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { BankCardTokenProvider, BankCardPaymentSystem, PaymentStatus } from '@vality/swag-anapi-v2';
|
||||
import { PaymentStatus, SearchPaymentsRequestParams } from '@vality/swag-anapi-v2';
|
||||
|
||||
import { CardFilterForm } from '../card-filter';
|
||||
import { InvoicesFilterForm } from '../invoices-filter';
|
||||
@ -10,8 +10,8 @@ export interface AdditionalFiltersForm {
|
||||
main: MainFiltersForm;
|
||||
paymentStatus: PaymentStatus.StatusEnum;
|
||||
paymentSum: PaymentSumFilterForm;
|
||||
tokenProvider: BankCardTokenProvider;
|
||||
paymentSystem: BankCardPaymentSystem;
|
||||
tokenProvider: SearchPaymentsRequestParams['bankCardTokenProvider'];
|
||||
paymentSystem: SearchPaymentsRequestParams['bankCardPaymentSystem'];
|
||||
invoices: InvoicesFilterForm;
|
||||
shops: ShopsFilterForm;
|
||||
binPan: CardFilterForm;
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { PaymentStatus, BankCardPaymentSystem, BankCardTokenProvider } from '@vality/swag-anapi-v2';
|
||||
import { PaymentStatus, SearchPaymentsRequestParams } from '@vality/swag-anapi-v2';
|
||||
|
||||
import { CardFilterForm } from '../card-filter';
|
||||
import { InvoicesFilterForm } from '../invoices-filter';
|
||||
@ -13,6 +13,6 @@ export type AdditionalFilters = Partial<MainFiltersForm> &
|
||||
Partial<CardFilterForm> & {
|
||||
binPan?: CardFilterForm;
|
||||
paymentStatus?: PaymentStatus.StatusEnum;
|
||||
tokenProvider?: BankCardTokenProvider;
|
||||
paymentSystem?: BankCardPaymentSystem;
|
||||
tokenProvider?: SearchPaymentsRequestParams['bankCardTokenProvider'];
|
||||
paymentSystem?: SearchPaymentsRequestParams['bankCardPaymentSystem'];
|
||||
};
|
||||
|
@ -12,7 +12,7 @@ import pick from 'lodash-es/pick';
|
||||
import { defer, ReplaySubject, BehaviorSubject, combineLatest } from 'rxjs';
|
||||
import { map, shareReplay } from 'rxjs/operators';
|
||||
|
||||
import { ShopsService } from '@dsh/api/payments';
|
||||
import { ShopsDataService } from '@dsh/app/shared';
|
||||
import { DateRange, Preset, createDateRangeWithPreset } from '@dsh/components/date-range-filter';
|
||||
import { ComponentChanges } from '@dsh/type-utils';
|
||||
import { getFormValueChanges } from '@dsh/utils';
|
||||
@ -40,7 +40,7 @@ export class PaymentsFiltersComponent implements OnInit, OnChanges {
|
||||
@Input() initParams: Filters;
|
||||
@Output() filtersChanged = new EventEmitter<MainFilters>();
|
||||
|
||||
shops$ = defer(() => this.realm$).pipe(filterShopsByRealm(this.shopService.shops$), shareReplay(1));
|
||||
shops$ = defer(() => this.realm$).pipe(filterShopsByRealm(this.shopsDataService.shops$), shareReplay(1));
|
||||
isAdditionalFilterApplied$ = defer(() => this.additionalFilters$).pipe(map(negate(isEmpty)));
|
||||
defaultDateRange = createDateRangeWithPreset(Preset.Last90days);
|
||||
form = this.fb.group<MainFilters>({
|
||||
@ -58,7 +58,7 @@ export class PaymentsFiltersComponent implements OnInit, OnChanges {
|
||||
private realm$ = new ReplaySubject<RealmEnum>(1);
|
||||
|
||||
constructor(
|
||||
private shopService: ShopsService,
|
||||
private shopsDataService: ShopsDataService,
|
||||
private fb: FormBuilder,
|
||||
private dialog: MatDialog,
|
||||
private mediaObserver: MediaObserver
|
||||
|
@ -1,22 +1,22 @@
|
||||
import {
|
||||
BankCardPaymentSystem,
|
||||
BankCardTokenProvider,
|
||||
PaymentTerminalProvider,
|
||||
SearchPaymentsRequestParams,
|
||||
} from '@vality/swag-anapi-v2';
|
||||
import { SearchPaymentsRequestParams } from '@vality/swag-anapi-v2';
|
||||
import { PaymentInstitution } from '@vality/swag-payments';
|
||||
|
||||
import RealmEnum = PaymentInstitution.RealmEnum;
|
||||
|
||||
export interface PaymentSearchFormValue {
|
||||
export interface PaymentSearchFormValue
|
||||
extends Pick<
|
||||
SearchPaymentsRequestParams,
|
||||
| 'paymentStatus'
|
||||
| 'paymentTerminalProvider'
|
||||
| 'bankCardTokenProvider'
|
||||
| 'bankCardPaymentSystem'
|
||||
| 'paymentMethod'
|
||||
| 'paymentFlow'
|
||||
> {
|
||||
realm: RealmEnum;
|
||||
fromTime: string;
|
||||
toTime: string;
|
||||
shopIDs?: string[];
|
||||
paymentStatus?: SearchPaymentsRequestParams['paymentStatus'];
|
||||
paymentFlow?: 'hold' | 'instant';
|
||||
paymentMethod?: 'bankCard' | 'paymentTerminal';
|
||||
paymentTerminalProvider?: PaymentTerminalProvider;
|
||||
invoiceIDs?: string[];
|
||||
invoiceID?: string;
|
||||
paymentID?: string;
|
||||
@ -26,8 +26,6 @@ export interface PaymentSearchFormValue {
|
||||
customerID?: string;
|
||||
first6?: string;
|
||||
last4?: string;
|
||||
bankCardTokenProvider?: BankCardTokenProvider;
|
||||
bankCardPaymentSystem?: BankCardPaymentSystem;
|
||||
paymentAmount?: number;
|
||||
rrn?: string;
|
||||
paymentAmountFrom?: number;
|
||||
|
@ -2,7 +2,7 @@ import { Component, Injector, ChangeDetectionStrategy } from '@angular/core';
|
||||
import { FormBuilder } from '@ngneat/reactive-forms';
|
||||
import { WrappedFormControlSuperclass, provideValueAccessor } from '@s-libs/ng-core';
|
||||
|
||||
import { ShopsService } from '@dsh/api/payments';
|
||||
import { ShopsDataService } from '@dsh/app/shared';
|
||||
|
||||
@Component({
|
||||
selector: 'dsh-shops-filter',
|
||||
@ -11,9 +11,9 @@ import { ShopsService } from '@dsh/api/payments';
|
||||
providers: [provideValueAccessor(ShopsFilterComponent)],
|
||||
})
|
||||
export class ShopsFilterComponent extends WrappedFormControlSuperclass<string[]> {
|
||||
shops$ = this.shopsService.shops$;
|
||||
shops$ = this.shopsDataService.shops$;
|
||||
|
||||
constructor(injector: Injector, private fb: FormBuilder, private shopsService: ShopsService) {
|
||||
constructor(injector: Injector, private fb: FormBuilder, private shopsDataService: ShopsDataService) {
|
||||
super(injector);
|
||||
}
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ import { MatSnackBar } from '@angular/material/snack-bar';
|
||||
import { TranslocoService } from '@ngneat/transloco';
|
||||
import { of } from 'rxjs';
|
||||
|
||||
import { ShopsService } from '@dsh/api/payments';
|
||||
import { ShopsDataService } from '@dsh/app/shared';
|
||||
import { amountValidator } from '@dsh/components/form-controls';
|
||||
|
||||
import { filterShopsByRealm, mapToShopInfo } from '../../operations/operators';
|
||||
@ -25,7 +25,7 @@ export class CreatePayoutDialogComponent implements OnInit {
|
||||
|
||||
currentPayoutToolCurrency: string;
|
||||
|
||||
shopsInfo$ = of(this.data.realm).pipe(filterShopsByRealm(this.shopsService.shops$), mapToShopInfo);
|
||||
shopsInfo$ = of(this.data.realm).pipe(filterShopsByRealm(this.shopsDataService.shops$), mapToShopInfo);
|
||||
|
||||
isPayoutToolsLoading$ = this.createPayoutDialogService.isLoading$;
|
||||
payoutTools$ = this.createPayoutDialogService.payoutTools$;
|
||||
@ -37,7 +37,7 @@ export class CreatePayoutDialogComponent implements OnInit {
|
||||
private createPayoutDialogService: CreatePayoutDialogService,
|
||||
private snackBar: MatSnackBar,
|
||||
private transloco: TranslocoService,
|
||||
private shopsService: ShopsService,
|
||||
private shopsDataService: ShopsDataService,
|
||||
@Inject(MAT_DIALOG_DATA) private data: { realm: string }
|
||||
) {}
|
||||
|
||||
|
@ -2,7 +2,8 @@ import { Injectable } from '@angular/core';
|
||||
import { BehaviorSubject, forkJoin, merge, of, Subject } from 'rxjs';
|
||||
import { catchError, filter, map, shareReplay, switchMap, take, tap } from 'rxjs/operators';
|
||||
|
||||
import { ShopsService, PayoutsService } from '@dsh/api/payments';
|
||||
import { PayoutsService } from '@dsh/api/payments';
|
||||
import { ShopsDataService } from '@dsh/app/shared';
|
||||
|
||||
import { toPayoutParams } from './to-payout-params';
|
||||
|
||||
@ -24,8 +25,8 @@ export class CreatePayoutDialogService {
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/member-ordering
|
||||
payoutTools$ = this.currentShopID$.pipe(
|
||||
switchMap((shopID) => this.shopsService.shops$.pipe(map((shops) => shops.find(({ id }) => id === shopID)))),
|
||||
switchMap(({ contractID }) => this.payoutsService.getPayoutTools({ contractID })),
|
||||
switchMap((shopID) => this.shopsDataService.shops$.pipe(map((shops) => shops.find(({ id }) => id === shopID)))),
|
||||
switchMap(({ contractID }) => this.payoutsService.getPayoutToolsForParty({ contractID })),
|
||||
map((tools) => tools.filter((tool) => tool.details.detailsType === 'PayoutToolDetailsWalletInfo')),
|
||||
shareReplay(1)
|
||||
);
|
||||
@ -36,7 +37,7 @@ export class CreatePayoutDialogService {
|
||||
shareReplay(1)
|
||||
);
|
||||
|
||||
constructor(private shopsService: ShopsService, private payoutsService: PayoutsService) {
|
||||
constructor(private shopsDataService: ShopsDataService, private payoutsService: PayoutsService) {
|
||||
merge(this.payoutTools$, this.hasPayoutTools$).subscribe();
|
||||
this.create$
|
||||
.pipe(
|
||||
@ -47,7 +48,7 @@ export class CreatePayoutDialogService {
|
||||
switchMap((params) =>
|
||||
forkJoin([
|
||||
of(params),
|
||||
this.shopsService.shops$.pipe(
|
||||
this.shopsDataService.shops$.pipe(
|
||||
take(1),
|
||||
map((shops) => shops.find(({ id }) => id === params.shopID)?.currency)
|
||||
),
|
||||
|
@ -6,7 +6,7 @@ import { TranslocoService } from '@ngneat/transloco';
|
||||
import moment from 'moment';
|
||||
import { of } from 'rxjs';
|
||||
|
||||
import { ShopsService } from '@dsh/api/payments';
|
||||
import { ShopsDataService } from '@dsh/app/shared';
|
||||
|
||||
import { filterShopsByRealm, mapToShopInfo } from '../../operations/operators';
|
||||
import { CreateReportDialogService } from './create-report-dialog.service';
|
||||
@ -21,7 +21,7 @@ const TIME_PATTERN = /^([0-9]|0[0-9]|1[0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]$/;
|
||||
})
|
||||
export class CreateReportDialogComponent implements OnInit {
|
||||
isLoading$ = this.createReportDialogService.isLoading$;
|
||||
shopsInfo$ = of(this.data.realm).pipe(filterShopsByRealm(this.shopService.shops$), mapToShopInfo);
|
||||
shopsInfo$ = of(this.data.realm).pipe(filterShopsByRealm(this.shopsDataService.shops$), mapToShopInfo);
|
||||
form = this.fb.group({
|
||||
fromDate: [moment().startOf('month').format(), Validators.required],
|
||||
fromTime: ['00:00:00', Validators.pattern(TIME_PATTERN)],
|
||||
@ -32,7 +32,7 @@ export class CreateReportDialogComponent implements OnInit {
|
||||
|
||||
constructor(
|
||||
private dialogRef: MatDialogRef<CreateReportDialogComponent, 'cancel' | 'created'>,
|
||||
private shopService: ShopsService,
|
||||
private shopsDataService: ShopsDataService,
|
||||
private fb: UntypedFormBuilder,
|
||||
private createReportDialogService: CreateReportDialogService,
|
||||
private transloco: TranslocoService,
|
||||
|
@ -3,7 +3,7 @@ import { Shop } from '@vality/swag-payments';
|
||||
import { combineLatest, Observable } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
|
||||
import { ShopsService } from '@dsh/api/payments';
|
||||
import { ShopsDataService } from '@dsh/app/shared';
|
||||
import { shareReplayRefCount } from '@dsh/operators';
|
||||
|
||||
import { getShopsByRealm } from '../operations/operators';
|
||||
@ -11,10 +11,10 @@ import { PaymentInstitutionRealmService } from './payment-institution-realm.serv
|
||||
|
||||
@Injectable()
|
||||
export class RealmShopsService {
|
||||
shops$: Observable<Shop[]> = combineLatest([this.shopsService.shops$, this.realmService.realm$]).pipe(
|
||||
shops$: Observable<Shop[]> = combineLatest([this.shopsDataService.shops$, this.realmService.realm$]).pipe(
|
||||
map(([shops, realm]) => (realm ? getShopsByRealm(shops, realm) : [])),
|
||||
shareReplayRefCount()
|
||||
);
|
||||
|
||||
constructor(private shopsService: ShopsService, private realmService: PaymentInstitutionRealmService) {}
|
||||
constructor(private shopsDataService: ShopsDataService, private realmService: PaymentInstitutionRealmService) {}
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ import isNil from 'lodash-es/isNil';
|
||||
import { BehaviorSubject, combineLatest, Observable, ReplaySubject } from 'rxjs';
|
||||
import { map, mapTo, pluck, scan, shareReplay, switchMap, tap, withLatestFrom } from 'rxjs/operators';
|
||||
|
||||
import { ShopsService } from '@dsh/api/payments';
|
||||
import { ShopsDataService } from '@dsh/app/shared';
|
||||
import { mapToTimestamp, shareReplayRefCount } from '@dsh/operators';
|
||||
|
||||
import { filterShopsByRealm } from '../../../operations/operators';
|
||||
@ -41,7 +41,7 @@ export class FetchShopsService {
|
||||
private filteredShops$: Observable<ShopItem[]>;
|
||||
|
||||
constructor(
|
||||
private shopsService: ShopsService,
|
||||
private shopsDataService: ShopsDataService,
|
||||
private shopsBalance: ShopsBalanceService,
|
||||
private filtersStore: ShopsFiltersStoreService,
|
||||
private filtersService: ShopsFiltersService,
|
||||
@ -69,7 +69,7 @@ export class FetchShopsService {
|
||||
|
||||
refreshData(): void {
|
||||
this.startLoading();
|
||||
this.shopsService.reloadShops();
|
||||
this.shopsDataService.reloadShops();
|
||||
}
|
||||
|
||||
showMore(): void {
|
||||
@ -97,7 +97,7 @@ export class FetchShopsService {
|
||||
}
|
||||
|
||||
private initAllShopsFetching(): void {
|
||||
this.allShops$ = this.realmData$.pipe(filterShopsByRealm(this.shopsService.shops$), shareReplayRefCount());
|
||||
this.allShops$ = this.realmData$.pipe(filterShopsByRealm(this.shopsDataService.shops$), shareReplayRefCount());
|
||||
}
|
||||
|
||||
private initOffsetObservable(): void {
|
||||
|
@ -32,7 +32,7 @@ export class ShopPayoutToolDetailsService {
|
||||
switchMap((payoutToolParams) =>
|
||||
payoutToolParams
|
||||
? this.payoutsService
|
||||
.getPayoutToolByID({
|
||||
.getPayoutToolByIDForParty({
|
||||
contractID: payoutToolParams.contractID,
|
||||
payoutToolID: payoutToolParams.payoutToolID,
|
||||
})
|
||||
|
@ -7,7 +7,7 @@ import { Shop } from '@vality/swag-payments';
|
||||
import cloneDeep from 'lodash-es/cloneDeep';
|
||||
import { of } from 'rxjs';
|
||||
|
||||
import { ShopsService } from '@dsh/api/payments';
|
||||
import { ShopsDataService } from '@dsh/app/shared';
|
||||
|
||||
import { generateMockShopItem } from '../../../../tests/generate-shop-item';
|
||||
import { ShopActionsService } from '../../services/shop-actions/shop-actions.service';
|
||||
@ -17,7 +17,7 @@ import { ShopActionsComponent } from './shop-actions.component';
|
||||
class MockShopsService {}
|
||||
|
||||
@Injectable()
|
||||
class MockApiShopsService extends ShopsService {
|
||||
class MockApiShopsService extends ShopsDataService {
|
||||
set mockShops(shops: Shop[]) {
|
||||
this._shops = shops;
|
||||
}
|
||||
@ -83,11 +83,11 @@ describe('ShopActionsComponent', () => {
|
||||
providers: [
|
||||
ShopActionsService,
|
||||
{
|
||||
provide: ShopsService,
|
||||
provide: ShopsDataService,
|
||||
useClass: MockApiShopsService,
|
||||
},
|
||||
{
|
||||
provide: ShopsService,
|
||||
provide: ShopsDataService,
|
||||
useClass: MockShopsService,
|
||||
},
|
||||
{
|
||||
|
@ -13,7 +13,7 @@ import { ShopActionResult } from '../../types/shop-action-result';
|
||||
@Injectable()
|
||||
export class ShopActionsService {
|
||||
constructor(
|
||||
private shopService: ShopsService,
|
||||
private shopsService: ShopsService,
|
||||
private dialog: MatDialog,
|
||||
private snackBar: MatSnackBar,
|
||||
private transloco: TranslocoService
|
||||
@ -25,7 +25,7 @@ export class ShopActionsService {
|
||||
.afterClosed()
|
||||
.pipe(
|
||||
filter((r) => r === 'confirm'),
|
||||
switchMap(() => this.shopService.suspendShop({ shopID })),
|
||||
switchMap(() => this.shopsService.suspendShopForParty({ shopID })),
|
||||
map(() => {
|
||||
this.snackBar.open(
|
||||
this.transloco.translate('shops.suspend.success', null, 'payment-section'),
|
||||
@ -49,7 +49,7 @@ export class ShopActionsService {
|
||||
.afterClosed()
|
||||
.pipe(
|
||||
filter((r) => r === 'confirm'),
|
||||
switchMap(() => this.shopService.activateShop({ shopID })),
|
||||
switchMap(() => this.shopsService.activateShopForParty({ shopID })),
|
||||
map(() => {
|
||||
this.snackBar.open(
|
||||
this.transloco.translate('shops.activate.success', null, 'payment-section'),
|
||||
|
@ -45,7 +45,7 @@ export class ReceiveWebhooksService {
|
||||
catchError((err) => {
|
||||
console.error(err);
|
||||
this.snackBar.open(this.transloco.translate('shared.httpError', null, 'components'), 'OK');
|
||||
return of([]);
|
||||
return of<Webhook[]>([]);
|
||||
})
|
||||
)
|
||||
),
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { ChangeDetectionStrategy, Component, Injector } from '@angular/core';
|
||||
import { provideValueAccessor } from '@s-libs/ng-core';
|
||||
import { RefundStatus } from '@vality/swag-dark-api';
|
||||
import { RefundStatus } from '@vality/swag-anapi-v2';
|
||||
|
||||
import { FilterSuperclass } from '@dsh/components/filter';
|
||||
|
||||
|
@ -4,7 +4,7 @@ import { Shop } from '@vality/swag-payments';
|
||||
import { combineLatest } from 'rxjs';
|
||||
import { map, share } from 'rxjs/operators';
|
||||
|
||||
import { ShopsService } from '@dsh/api/payments';
|
||||
import { ShopsDataService } from '@dsh/app/shared';
|
||||
import { FilterSuperclass } from '@dsh/components/filter';
|
||||
|
||||
@Component({
|
||||
@ -16,14 +16,14 @@ import { FilterSuperclass } from '@dsh/components/filter';
|
||||
export class ShopsFilterComponent extends FilterSuperclass<Shop['id'][]> {
|
||||
@Input() shops: Shop[];
|
||||
|
||||
labels$ = combineLatest([this.savedValue$, this.shopsService.shops$]).pipe(
|
||||
labels$ = combineLatest([this.savedValue$, this.shopsDataService.shops$]).pipe(
|
||||
map(([selectedShopIds, shops]) =>
|
||||
(selectedShopIds || []).map((id) => shops.find((s) => s.id === id)?.details?.name || id)
|
||||
),
|
||||
share()
|
||||
);
|
||||
|
||||
constructor(injector: Injector, private shopsService: ShopsService) {
|
||||
constructor(injector: Injector, private shopsDataService: ShopsDataService) {
|
||||
super(injector);
|
||||
}
|
||||
}
|
||||
|
@ -1,16 +1,16 @@
|
||||
import { Pipe, PipeTransform } from '@angular/core';
|
||||
import { RefundStatus } from '@vality/swag-dark-api';
|
||||
import { RefundStatus } from '@vality/swag-anapi-v2';
|
||||
import { Observable, of } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
|
||||
import { DarkApiDictionaryService } from '@dsh/api/dark-api/dark-api-dictionary.service';
|
||||
import { AnapiDictionaryService } from '@dsh/api/anapi';
|
||||
|
||||
@Pipe({ name: 'refundStatusLabel' })
|
||||
export class RefundStatusLabelPipe implements PipeTransform {
|
||||
constructor(private darkApiDictionaryService: DarkApiDictionaryService) {}
|
||||
constructor(private anapiDictionaryService: AnapiDictionaryService) {}
|
||||
|
||||
transform(value: RefundStatus.StatusEnum): Observable<string> {
|
||||
if (!value) return of('');
|
||||
return this.darkApiDictionaryService.refundStatus$.pipe(map((d) => d[value]));
|
||||
return this.anapiDictionaryService.refundStatus$.pipe(map((d) => d[value]));
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { ChangeDetectionStrategy, Component, Injector } from '@angular/core';
|
||||
import { provideValueAccessor, WrappedFormControlSuperclass } from '@s-libs/ng-core';
|
||||
import { RefundStatus } from '@vality/swag-dark-api';
|
||||
import { RefundStatus } from '@vality/swag-anapi-v2';
|
||||
import { combineLatest, Observable } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { RefundStatus } from '@vality/swag-dark-api';
|
||||
import { RefundStatus } from '@vality/swag-anapi-v2';
|
||||
|
||||
export const OPTION_LABELS: { [N in RefundStatus.StatusEnum]: string } = {
|
||||
succeeded: 'succeeded',
|
||||
|
@ -4,7 +4,8 @@ import { Shop } from '@vality/swag-payments';
|
||||
import { defer, Observable } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
|
||||
import { ShopsService, toLiveShops } from '@dsh/api/payments';
|
||||
import { toLiveShops } from '@dsh/api/payments';
|
||||
import { ShopsDataService } from '@dsh/app/shared';
|
||||
import { shopToOption } from '@dsh/app/shared/components/inputs/shop-field/utils/shops-to-options';
|
||||
import { Option } from '@dsh/components/form-controls/select-search-field';
|
||||
import { shareReplayRefCount } from '@dsh/operators';
|
||||
@ -23,7 +24,7 @@ export class ShopFieldComponent extends WrappedFormControlSuperclass<Shop> {
|
||||
@Input() @coerceBoolean required = false;
|
||||
|
||||
options$: Observable<Option<Shop>[]> = defer(
|
||||
() => this.shops$ || this.shopsService.shops$.pipe(map(toLiveShops))
|
||||
() => this.shops$ || this.shopsDataService.shops$.pipe(map(toLiveShops))
|
||||
).pipe(
|
||||
map((shops) => shops.map(shopToOption)),
|
||||
shareReplayRefCount()
|
||||
@ -31,7 +32,7 @@ export class ShopFieldComponent extends WrappedFormControlSuperclass<Shop> {
|
||||
|
||||
constructor(
|
||||
injector: Injector,
|
||||
private shopsService: ShopsService,
|
||||
private shopsDataService: ShopsDataService,
|
||||
@Inject(SHOPS)
|
||||
@Optional()
|
||||
private shops$?: Observable<Shop[]>
|
||||
|
@ -71,7 +71,7 @@ export class ExistingBankAccountComponent extends ValidatedControlSuperclass<Exi
|
||||
|
||||
private getPayoutToolByShop(shop: Shop): Observable<PayoutTool> {
|
||||
return this.payoutsService
|
||||
.getPayoutToolByID({ contractID: shop.contractID, payoutToolID: shop.payoutToolID })
|
||||
.getPayoutToolByIDForParty({ contractID: shop.contractID, payoutToolID: shop.payoutToolID })
|
||||
.pipe(
|
||||
switchMap((payoutTool) => {
|
||||
if (payoutTool.details.detailsType !== this.bankAccountType)
|
||||
|
@ -61,7 +61,7 @@ export class ExistingContractFormComponent extends ValidatedControlSuperclass<Ex
|
||||
}
|
||||
|
||||
private getContract(contractID: Contract['id']): Observable<ExistingContractForm> {
|
||||
return this.contractsService.getContractByID({ contractID }).pipe(
|
||||
return this.contractsService.getContractByIDForParty({ contractID }).pipe(
|
||||
switchMap((contract: ExistingContractForm) => {
|
||||
if (contract.contractor.entityType !== this.entityType)
|
||||
return (
|
||||
|
@ -2,7 +2,7 @@ import { ChangeDetectorRef, OnDestroy, Pipe, PipeTransform } from '@angular/core
|
||||
import { BehaviorSubject, combineLatest, Subject } from 'rxjs';
|
||||
import { distinctUntilChanged, map, takeUntil } from 'rxjs/operators';
|
||||
|
||||
import { ShopsService } from '@dsh/api/payments';
|
||||
import { ShopsDataService } from '@dsh/app/shared';
|
||||
|
||||
@Pipe({
|
||||
name: 'shopDetails',
|
||||
@ -13,8 +13,8 @@ export class ShopDetailsPipe implements PipeTransform, OnDestroy {
|
||||
private shopIDChange$: Subject<string> = new Subject();
|
||||
private destroy$: Subject<void> = new Subject();
|
||||
|
||||
constructor(private shopService: ShopsService, private ref: ChangeDetectorRef) {
|
||||
combineLatest([this.shopService.shops$, this.shopIDChange$.pipe(distinctUntilChanged())])
|
||||
constructor(private shopsDataService: ShopsDataService, private ref: ChangeDetectorRef) {
|
||||
combineLatest([this.shopsDataService.shops$, this.shopIDChange$.pipe(distinctUntilChanged())])
|
||||
.pipe(
|
||||
takeUntil(this.destroy$),
|
||||
map(([shops, shopID]) => shops.find((s) => s.id === shopID)?.details?.name || shopID)
|
||||
|
@ -2,27 +2,28 @@ import { HttpErrorResponse } from '@angular/common/http';
|
||||
import { Injectable } from '@angular/core';
|
||||
import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy';
|
||||
import { Organization, Member, RoleId } from '@vality/swag-organizations';
|
||||
import isNil from 'lodash-es/isNil';
|
||||
import { Observable, ReplaySubject, EMPTY, concat, defer, combineLatest, of, throwError } from 'rxjs';
|
||||
import { switchMap, shareReplay, catchError, map, tap } from 'rxjs/operators';
|
||||
import { switchMap, shareReplay, catchError, map, tap, filter } from 'rxjs/operators';
|
||||
|
||||
import { OrgsService, MembersService } from '@dsh/api/organizations';
|
||||
import { OrgsService, MembersService, DEFAULT_ORGANIZATION_NAME } from '@dsh/api/organizations';
|
||||
import { KeycloakTokenInfoService } from '@dsh/app/shared/services/keycloak-token-info';
|
||||
|
||||
import { ErrorService } from '../error';
|
||||
import { KeycloakTokenInfoService } from '../keycloak-token-info';
|
||||
|
||||
@UntilDestroy()
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class ContextService {
|
||||
export class ContextOrganizationService {
|
||||
organization$: Observable<Organization> = concat(
|
||||
this.organizationsService.getContext().pipe(
|
||||
map(({ organizationId }) => organizationId),
|
||||
catchError((err) => {
|
||||
if (err instanceof HttpErrorResponse && err.status === 404)
|
||||
return this.organizationsService.listOrgMembership({ limit: 1 }).pipe(
|
||||
map(({ result }) => result[0].id),
|
||||
tap((id) => this.switchOrganization(id)),
|
||||
switchMap(({ result }) => (result[0] ? of(result[0]) : this.createOrganization())),
|
||||
tap(({ id }) => this.switchOrganization(id)),
|
||||
switchMap(() => EMPTY)
|
||||
);
|
||||
console.error(err);
|
||||
@ -42,6 +43,7 @@ export class ContextService {
|
||||
shareReplay(1)
|
||||
);
|
||||
member$ = combineLatest([this.organization$, this.keycloakTokenInfoService.userID$]).pipe(
|
||||
filter(([org, userId]) => !isNil(org) && !isNil(userId)),
|
||||
switchMap(([{ id: orgId }, userId]) =>
|
||||
this.membersService.getOrgMember({ orgId, userId }).pipe(
|
||||
catchError((error) => {
|
||||
@ -73,4 +75,10 @@ export class ContextService {
|
||||
switchOrganization(organizationId: string): void {
|
||||
this.switchOrganization$.next(organizationId);
|
||||
}
|
||||
|
||||
private createOrganization(): Observable<Organization> {
|
||||
return this.organizationsService.createOrg({
|
||||
organization: { name: DEFAULT_ORGANIZATION_NAME } as Organization,
|
||||
});
|
||||
}
|
||||
}
|
1
src/app/shared/services/context-organization/index.ts
Normal file
1
src/app/shared/services/context-organization/index.ts
Normal file
@ -0,0 +1 @@
|
||||
export * from './context-organization.service';
|
@ -1 +0,0 @@
|
||||
export * from './context.service';
|
@ -9,4 +9,5 @@ export * from './sections-links';
|
||||
export * from './query-params';
|
||||
export * from './id-generator';
|
||||
export * from './partial-fetcher';
|
||||
export * from './context';
|
||||
export * from './context-organization';
|
||||
export * from './shops-data';
|
||||
|
@ -4,7 +4,7 @@ import { combineLatest, defer, Observable, ReplaySubject } from 'rxjs';
|
||||
import { map, pluck, shareReplay, switchMap } from 'rxjs/operators';
|
||||
|
||||
import { MembersService } from '@dsh/api/organizations';
|
||||
import { ContextService } from '@dsh/app/shared';
|
||||
import { ContextOrganizationService } from '@dsh/app/shared';
|
||||
import { Initializable } from '@dsh/app/shared/types';
|
||||
import { SHARE_REPLAY_CONF } from '@dsh/operators';
|
||||
|
||||
@ -16,12 +16,12 @@ export class OrganizationManagementService implements Initializable {
|
||||
shareReplay(SHARE_REPLAY_CONF)
|
||||
);
|
||||
isOrganizationOwner$: Observable<boolean> = defer(() =>
|
||||
combineLatest([this.organization$, this.contextService.organization$.pipe(pluck('party'))])
|
||||
combineLatest([this.organization$, this.contextOrganizationService.organization$.pipe(pluck('party'))])
|
||||
).pipe(
|
||||
map(([{ owner }, id]) => owner === id),
|
||||
shareReplay(SHARE_REPLAY_CONF)
|
||||
);
|
||||
isOrganizationAdmin$: Observable<boolean> = this.contextService.member$.pipe(
|
||||
isOrganizationAdmin$: Observable<boolean> = this.contextOrganizationService.member$.pipe(
|
||||
map((member) => member.roles.findIndex((r) => r.roleId === RoleId.Administrator) !== -1),
|
||||
shareReplay(SHARE_REPLAY_CONF)
|
||||
);
|
||||
@ -34,7 +34,10 @@ export class OrganizationManagementService implements Initializable {
|
||||
|
||||
private organization$ = new ReplaySubject<Organization>();
|
||||
|
||||
constructor(private membersService: MembersService, private contextService: ContextService) {}
|
||||
constructor(
|
||||
private membersService: MembersService,
|
||||
private contextOrganizationService: ContextOrganizationService
|
||||
) {}
|
||||
|
||||
init(organization: Organization) {
|
||||
this.organization$.next(organization);
|
||||
|
@ -31,7 +31,7 @@ export class ShopContractDetailsService {
|
||||
tap(() => this._isLoading$.next(true)),
|
||||
switchMap((contractID) =>
|
||||
contractID
|
||||
? this.contractsService.getContractByID({ contractID }).pipe(
|
||||
? this.contractsService.getContractByIDForParty({ contractID }).pipe(
|
||||
catchError((e) => {
|
||||
console.error(e);
|
||||
this.error$.next(true);
|
||||
|
1
src/app/shared/services/shops-data/index.ts
Normal file
1
src/app/shared/services/shops-data/index.ts
Normal file
@ -0,0 +1 @@
|
||||
export * from './shops-data.service';
|
63
src/app/shared/services/shops-data/shops-data.service.ts
Normal file
63
src/app/shared/services/shops-data/shops-data.service.ts
Normal file
@ -0,0 +1,63 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Shop } from '@vality/swag-payments';
|
||||
import { Observable, Subject, of, repeat } from 'rxjs';
|
||||
import { startWith, switchMap, takeWhile } from 'rxjs/operators';
|
||||
|
||||
import { createTestShopClaimChangeset, ClaimsService } from '@dsh/api/claim-management';
|
||||
import { ShopsService } from '@dsh/api/payments';
|
||||
import { ContextOrganizationService } from '@dsh/app/shared';
|
||||
import { shareReplayRefCount } from '@dsh/operators';
|
||||
|
||||
import { IdGeneratorService } from '../id-generator';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class ShopsDataService {
|
||||
shops$: Observable<Shop[]> = this.contextOrganizationService.organization$.pipe(
|
||||
switchMap(() => this.reloadShops$),
|
||||
startWith(this.shopsService.getShopsForParty()),
|
||||
switchMap((shops$) => shops$),
|
||||
switchMap((shops) => (shops.length ? of(shops) : this.createTestShop())),
|
||||
shareReplayRefCount()
|
||||
);
|
||||
|
||||
private reloadShops$ = new Subject<Observable<Shop[]>>();
|
||||
|
||||
constructor(
|
||||
private shopsService: ShopsService,
|
||||
private contextOrganizationService: ContextOrganizationService,
|
||||
private idGenerator: IdGeneratorService,
|
||||
private claimsService: ClaimsService
|
||||
) {}
|
||||
|
||||
reloadShops(): Observable<Shop[]> {
|
||||
const shop$ = this.shopsService.getShopsForParty();
|
||||
this.reloadShops$.next(shop$);
|
||||
return shop$;
|
||||
}
|
||||
|
||||
private createTestShop(): Observable<Shop[]> {
|
||||
return this.claimsService
|
||||
.searchClaims({ limit: 1 })
|
||||
.pipe(
|
||||
switchMap((claims) =>
|
||||
claims.result.length
|
||||
? of(claims.result[0])
|
||||
: this.claimsService.createClaim({
|
||||
changeset: createTestShopClaimChangeset(
|
||||
this.idGenerator.uuid(),
|
||||
this.idGenerator.uuid(),
|
||||
this.idGenerator.uuid(),
|
||||
this.idGenerator.uuid()
|
||||
),
|
||||
})
|
||||
)
|
||||
)
|
||||
.pipe(
|
||||
switchMap(() => this.shopsService.getShopsForParty()),
|
||||
repeat({ count: 2, delay: 1000 }),
|
||||
takeWhile((shops) => !shops.length)
|
||||
);
|
||||
}
|
||||
}
|
@ -33,11 +33,6 @@
|
||||
"emptySearchResult": {
|
||||
"empty": "No data available for this period"
|
||||
},
|
||||
"fileUploader": {
|
||||
"choose": "select",
|
||||
"forUpload": "To upload, move the files to the area, or",
|
||||
"uploading": "Loading..."
|
||||
},
|
||||
"humanizeDuration": {
|
||||
"ago": "ago",
|
||||
"justNow": "just now",
|
||||
|
@ -33,11 +33,6 @@
|
||||
"emptySearchResult": {
|
||||
"empty": "Данные за указанный период отсутствуют"
|
||||
},
|
||||
"fileUploader": {
|
||||
"choose": "выберите",
|
||||
"forUpload": "Для загрузки переместите файлы в область, или",
|
||||
"uploading": "Загрузка..."
|
||||
},
|
||||
"humanizeDuration": {
|
||||
"ago": "назад",
|
||||
"justNow": "только что",
|
||||
|
@ -93,13 +93,6 @@
|
||||
"revoked": "Revoked"
|
||||
}
|
||||
},
|
||||
"darkApi": {
|
||||
"refundStatus": {
|
||||
"failed": "Failed",
|
||||
"pending": "Pending",
|
||||
"succeeded": "Succeeded"
|
||||
}
|
||||
},
|
||||
"organizations": {
|
||||
"resourceScopeId": {
|
||||
"Shop": "Shops"
|
||||
|
@ -93,13 +93,6 @@
|
||||
"revoked": "Отозвана"
|
||||
}
|
||||
},
|
||||
"darkApi": {
|
||||
"refundStatus": {
|
||||
"failed": "Неуспешен",
|
||||
"pending": "Запущен",
|
||||
"succeeded": "Успешен"
|
||||
}
|
||||
},
|
||||
"organizations": {
|
||||
"resourceScopeId": {
|
||||
"Shop": "Магазины"
|
||||
|
@ -1,21 +0,0 @@
|
||||
@use '@angular/material' as mat;
|
||||
|
||||
@mixin dsh-file-uploader-theme($theme) {
|
||||
$primary: map-get($theme, primary);
|
||||
$foreground: map-get($theme, foreground);
|
||||
|
||||
.dsh-file-uploader {
|
||||
&-container {
|
||||
border-color: map-get($foreground, border);
|
||||
|
||||
&-dragover {
|
||||
border-color: mat.get-color-from-palette($primary, default);
|
||||
transition: ease 1s;
|
||||
}
|
||||
}
|
||||
|
||||
&-choose-files {
|
||||
color: mat.get-color-from-palette($primary, default);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
<div
|
||||
ngfDrop
|
||||
(dragenter)="setDragover(true)"
|
||||
(dragleave)="setDragover(false)"
|
||||
(filesChange)="startUploading($event)"
|
||||
class="dsh-file-uploader-container"
|
||||
[class.dsh-file-uploader-container-dragover]="isDragover"
|
||||
fxFlex
|
||||
fxLayoutAlign="center"
|
||||
>
|
||||
<div *transloco="let t; scope: 'core-components'; read: 'coreComponents.fileUploader'">
|
||||
<div *ngIf="!(isUploading$ | async); else uploading">
|
||||
{{ t('forUpload') }}
|
||||
<span ngfSelect (filesChange)="startUploading($event)" class="dsh-file-uploader-choose-files">{{
|
||||
t('choose')
|
||||
}}</span
|
||||
>.
|
||||
</div>
|
||||
<ng-template #uploading>{{ t('uploading') }}</ng-template>
|
||||
</div>
|
||||
</div>
|
@ -1,17 +0,0 @@
|
||||
.dsh-file-uploader {
|
||||
&-container {
|
||||
border: 2px dashed;
|
||||
padding: 15px 0;
|
||||
box-sizing: border-box;
|
||||
border-radius: 4px;
|
||||
|
||||
&-dragover {
|
||||
border: 2px solid;
|
||||
transition: ease 1s;
|
||||
}
|
||||
}
|
||||
|
||||
&-choose-files {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
@ -1,31 +0,0 @@
|
||||
import { Component, EventEmitter, HostBinding, Output } from '@angular/core';
|
||||
|
||||
import { FileUploaderService } from './file-uploader.service';
|
||||
|
||||
@Component({
|
||||
selector: 'dsh-file-uploader',
|
||||
templateUrl: 'file-uploader.component.html',
|
||||
styleUrls: ['file-uploader.component.scss'],
|
||||
})
|
||||
export class FileUploaderComponent {
|
||||
@Output()
|
||||
filesUploaded = new EventEmitter<string[]>();
|
||||
|
||||
@HostBinding('class.dsh-file-uploader-container')
|
||||
isDragover = false;
|
||||
|
||||
startUploading$ = this.fileUploaderService.startUploading$;
|
||||
isUploading$ = this.fileUploaderService.isUploading$;
|
||||
|
||||
constructor(private fileUploaderService: FileUploaderService) {
|
||||
this.fileUploaderService.filesUploaded$.subscribe((value) => this.filesUploaded.emit(value));
|
||||
}
|
||||
|
||||
setDragover(value: boolean) {
|
||||
this.isDragover = value;
|
||||
}
|
||||
|
||||
startUploading(files: File[]) {
|
||||
this.startUploading$.next(files);
|
||||
}
|
||||
}
|
@ -1,16 +0,0 @@
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { NgModule } from '@angular/core';
|
||||
import { FlexModule } from '@angular/flex-layout';
|
||||
import { TranslocoModule } from '@ngneat/transloco';
|
||||
import { ngfModule } from 'angular-file';
|
||||
|
||||
import { FileUploaderComponent } from './file-uploader.component';
|
||||
import { FileUploaderService } from './file-uploader.service';
|
||||
|
||||
@NgModule({
|
||||
imports: [TranslocoModule, FlexModule, ngfModule, CommonModule],
|
||||
exports: [FileUploaderComponent],
|
||||
declarations: [FileUploaderComponent],
|
||||
providers: [FileUploaderService],
|
||||
})
|
||||
export class FileUploaderModule {}
|
@ -1,40 +0,0 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { MatSnackBar } from '@angular/material/snack-bar';
|
||||
import { TranslocoService } from '@ngneat/transloco';
|
||||
import { merge, of, Subject } from 'rxjs';
|
||||
import { catchError, filter, shareReplay, switchMap } from 'rxjs/operators';
|
||||
|
||||
import { FilesService } from '@dsh/api/dark-api';
|
||||
import { progress } from '@dsh/operators';
|
||||
|
||||
@Injectable()
|
||||
export class FileUploaderService {
|
||||
startUploading$ = new Subject<File[]>();
|
||||
|
||||
filesUploadingError$ = new Subject<null>();
|
||||
|
||||
filesUploaded$ = this.startUploading$.pipe(
|
||||
switchMap((files) =>
|
||||
this.filesService.uploadFiles(files).pipe(
|
||||
catchError(() => {
|
||||
this.filesUploadingError$.next(null);
|
||||
return of([]);
|
||||
})
|
||||
)
|
||||
),
|
||||
filter((v) => !!v.length),
|
||||
shareReplay(1)
|
||||
);
|
||||
|
||||
isUploading$ = progress(this.startUploading$, merge(this.filesUploaded$, this.filesUploadingError$));
|
||||
|
||||
constructor(
|
||||
private filesService: FilesService,
|
||||
private snackBar: MatSnackBar,
|
||||
private transloco: TranslocoService
|
||||
) {
|
||||
this.filesUploadingError$.subscribe(() =>
|
||||
this.snackBar.open(this.transloco.translate('shared.commonError', null, 'components'), 'OK')
|
||||
);
|
||||
}
|
||||
}
|
@ -1,2 +0,0 @@
|
||||
export * from './file-uploader.module';
|
||||
export * from './file-uploader.component';
|
@ -1,10 +1,9 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
|
||||
import { FileUploaderModule } from './file-uploader';
|
||||
import { FormatInputModule } from './format-input';
|
||||
import { SelectSearchFieldModule } from './select-search-field';
|
||||
|
||||
const EXPORTED_DECLARATIONS = [FormatInputModule, FileUploaderModule, SelectSearchFieldModule];
|
||||
const EXPORTED_DECLARATIONS = [FormatInputModule, SelectSearchFieldModule];
|
||||
|
||||
@NgModule({
|
||||
imports: EXPORTED_DECLARATIONS,
|
||||
|
@ -3,4 +3,3 @@ export * from './masks';
|
||||
export * from './validators';
|
||||
export * from './format-input';
|
||||
export * from './utils';
|
||||
export * from './file-uploader';
|
||||
|
@ -1,4 +1,3 @@
|
||||
@import '../../components/form-controls/file-uploader/file-uploader-theme';
|
||||
@import '../../components/buttons/button/button-theme';
|
||||
@import '../../components/buttons/button-toggle/button-toggle-theme';
|
||||
@import '../../components/layout/card/card-theme';
|
||||
@ -44,7 +43,6 @@
|
||||
@include dsh-status-theme($theme);
|
||||
@include dsh-dadata-autocomplete-theme($theme);
|
||||
@include dsh-details-item-theme($theme);
|
||||
@include dsh-file-uploader-theme($theme);
|
||||
@include dsh-panel-theme($theme);
|
||||
@include dsh-bar-chart-theme($theme);
|
||||
@include dsh-percent-difference-theme($theme);
|
||||
|
Loading…
Reference in New Issue
Block a user