IMP-161: Add withdrawals external id (#168)

This commit is contained in:
Rinat Arsaev 2024-02-05 14:44:54 +07:00 committed by GitHub
parent 1cd2ab6a29
commit 881903ccdd
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 61 additions and 17 deletions

View File

@ -8,7 +8,7 @@
"fix": "npm run lint:fix && npm run format:fix && npm run spell:fix", "fix": "npm run lint:fix && npm run format:fix && npm run spell:fix",
"build": "ng build && transloco-optimize dist/assets/i18n", "build": "ng build && transloco-optimize dist/assets/i18n",
"test": "ng test", "test": "ng test",
"i18n:extract": "transloco-keys-manager extract && prettier src/assets/i18n/* --write", "i18n:extract": "transloco-keys-manager extract && prettier src/assets/i18n/** --write",
"i18n:clean": "transloco-keys-manager extract --remove-extra-keys && prettier src/assets/i18n/* --write", "i18n:clean": "transloco-keys-manager extract --remove-extra-keys && prettier src/assets/i18n/* --write",
"i18n:check": "transloco-keys-manager find --emit-error-on-extra-keys", "i18n:check": "transloco-keys-manager find --emit-error-on-extra-keys",
"coverage": "npx http-server -c-1 -o -p 9875 ./coverage", "coverage": "npx http-server -c-1 -o -p 9875 ./coverage",

View File

@ -1,8 +1,29 @@
<dsh-home> <dsh-home *transloco="let t; scope: 'app'; read: 'app'">
<dsh-sections *ngIf="bootstrapped$ | async; else spinner"></dsh-sections> <dsh-sections *ngIf="bootstrapped$ | async; else spinner"></dsh-sections>
<ng-template #spinner> <ng-template #spinner>
<div fxFlexAlign="center" fxLayout="row"> <div fxFlexAlign="center" fxLayout="row">
<dsh-spinner style="margin: auto"></dsh-spinner> <dsh-spinner style="margin: auto"></dsh-spinner>
</div> </div>
</ng-template> </ng-template>
<div *ngIf="isDev" style="display: flex; justify-content: center">
<div
[matMenuTriggerFor]="menu"
class="dsh-body-2"
style="cursor: pointer; display: flex; gap: 8px; align-items: center"
>
<dsh-bi icon="globe" size="sm"></dsh-bi>
<!-- t(language.en) -->
<!-- t(language.ru) -->
{{ t('language.' + languageService.active) }}
</div>
<mat-menu #menu="matMenu">
<button
*ngFor="let language of languageService.list"
mat-menu-item
(click)="languageService.set(language)"
>
{{ t('language.' + language) }}
</button>
</mat-menu>
</div>
</dsh-home> </dsh-home>

View File

@ -1,7 +1,9 @@
import { Component, OnInit } from '@angular/core'; import { Component, OnInit, isDevMode } from '@angular/core';
import * as sentry from '@sentry/angular-ivy'; import * as sentry from '@sentry/angular-ivy';
import { first } from 'rxjs/operators'; import { first } from 'rxjs/operators';
import { LanguageService } from '@dsh/app/language';
import { BootstrapService } from './bootstrap.service'; import { BootstrapService } from './bootstrap.service';
import { ContextOrganizationService } from './shared'; import { ContextOrganizationService } from './shared';
@ -12,10 +14,12 @@ import { ContextOrganizationService } from './shared';
}) })
export class AppComponent implements OnInit { export class AppComponent implements OnInit {
bootstrapped$ = this.bootstrapService.bootstrapped$; bootstrapped$ = this.bootstrapService.bootstrapped$;
isDev = isDevMode();
constructor( constructor(
private bootstrapService: BootstrapService, private bootstrapService: BootstrapService,
private contextOrganizationService: ContextOrganizationService, private contextOrganizationService: ContextOrganizationService,
public languageService: LanguageService,
) {} ) {}
ngOnInit(): void { ngOnInit(): void {

View File

@ -1,6 +1,7 @@
import { CommonModule } from '@angular/common'; import { CommonModule } from '@angular/common';
import { HTTP_INTERCEPTORS, HttpClientModule } from '@angular/common/http'; import { HTTP_INTERCEPTORS, HttpClientModule } from '@angular/common/http';
import { APP_INITIALIZER, ErrorHandler, LOCALE_ID, NgModule, isDevMode } from '@angular/core'; import { APP_INITIALIZER, ErrorHandler, LOCALE_ID, NgModule, isDevMode } from '@angular/core';
import { MatButtonModule } from '@angular/material/button';
import { import {
DateAdapter, DateAdapter,
MAT_DATE_FORMATS, MAT_DATE_FORMATS,
@ -9,6 +10,7 @@ import {
} from '@angular/material/core'; } from '@angular/material/core';
import { MatDialogModule } from '@angular/material/dialog'; import { MatDialogModule } from '@angular/material/dialog';
import { MAT_FORM_FIELD_DEFAULT_OPTIONS } from '@angular/material/form-field'; import { MAT_FORM_FIELD_DEFAULT_OPTIONS } from '@angular/material/form-field';
import { MatMenuModule } from '@angular/material/menu';
import { import {
MAT_MOMENT_DATE_ADAPTER_OPTIONS, MAT_MOMENT_DATE_ADAPTER_OPTIONS,
MAT_MOMENT_DATE_FORMATS, MAT_MOMENT_DATE_FORMATS,
@ -17,7 +19,7 @@ import {
import { BrowserModule } from '@angular/platform-browser'; import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { Router } from '@angular/router'; import { Router } from '@angular/router';
import { TranslocoModule, provideTransloco } from '@ngneat/transloco'; import { TranslocoModule, provideTransloco, TRANSLOCO_SCOPE } from '@ngneat/transloco';
import * as sentry from '@sentry/angular-ivy'; import * as sentry from '@sentry/angular-ivy';
import { FlexLayoutModule } from 'ng-flex-layout'; import { FlexLayoutModule } from 'ng-flex-layout';
@ -29,7 +31,7 @@ import { WalletModule } from '@dsh/app/api/wallet';
import { ErrorModule } from '@dsh/app/shared/services'; import { ErrorModule } from '@dsh/app/shared/services';
import { QUERY_PARAMS_SERIALIZERS } from '@dsh/app/shared/services/query-params/utils/query-params-serializers'; import { QUERY_PARAMS_SERIALIZERS } from '@dsh/app/shared/services/query-params/utils/query-params-serializers';
import { createDateRangeWithPresetSerializer } from '@dsh/components/date-range-filter'; import { createDateRangeWithPresetSerializer } from '@dsh/components/date-range-filter';
import { SpinnerModule } from '@dsh/components/indicators'; import { SpinnerModule, BootstrapIconModule } from '@dsh/components/indicators';
import { ENV, environment } from '../environments'; import { ENV, environment } from '../environments';
@ -72,6 +74,9 @@ import { TranslocoHttpLoaderService } from './transloco-http-loader.service';
WalletModule, WalletModule,
SpinnerModule, SpinnerModule,
ApiKeysModule, ApiKeysModule,
MatButtonModule,
BootstrapIconModule,
MatMenuModule,
], ],
providers: [ providers: [
LanguageService, LanguageService,
@ -135,6 +140,7 @@ import { TranslocoHttpLoaderService } from './transloco-http-loader.service';
provide: QUERY_PARAMS_SERIALIZERS, provide: QUERY_PARAMS_SERIALIZERS,
useValue: [createDateRangeWithPresetSerializer()], useValue: [createDateRangeWithPresetSerializer()],
}, },
{ provide: TRANSLOCO_SCOPE, useValue: 'app' },
], ],
bootstrap: [AppComponent], bootstrap: [AppComponent],
}) })

View File

@ -11,6 +11,7 @@ import { LANGUAGES, Language } from './languages';
@Injectable({ providedIn: 'root' }) @Injectable({ providedIn: 'root' })
export class LanguageService { export class LanguageService {
active: Language; active: Language;
list = LANGUAGES;
private static readonly key = 'language'; private static readonly key = 'language';
@ -20,9 +21,7 @@ export class LanguageService {
) {} ) {}
async init() { async init() {
// TODO: Use after language change support starts const storageLang = this.settingsService.getLocalStorageItem(LanguageService.key);
// const storageLang = this.settingsService.getLocalStorageItem(LanguageService.key);
const storageLang = null;
let language: Language; let language: Language;
if (Array.from<string>(LANGUAGES).includes(storageLang)) { if (Array.from<string>(LANGUAGES).includes(storageLang)) {
language = storageLang as Language; language = storageLang as Language;
@ -37,8 +36,7 @@ export class LanguageService {
await this.set(language); await this.set(language);
} }
// TODO: Make it public after language change support starts async set(language: Language) {
private async set(language: Language) {
this.active = language; this.active = language;
registerLocaleData(ANGULAR_LOCALE_DATA[language], language); registerLocaleData(ANGULAR_LOCALE_DATA[language], language);
if (language !== 'en') { if (language !== 'en') {

View File

@ -3,8 +3,8 @@ import { ActivatedRoute, Router } from '@angular/router';
import { TranslocoService } from '@ngneat/transloco'; import { TranslocoService } from '@ngneat/transloco';
import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy';
import { PaymentInstitution } from '@vality/swag-payments'; import { PaymentInstitution } from '@vality/swag-payments';
import { combineLatest, Observable, Subject } from 'rxjs'; import { combineLatest, Observable, Subject, defer, ReplaySubject } from 'rxjs';
import { filter, map, pluck, switchMapTo, first } from 'rxjs/operators'; import { filter, map, switchMapTo, first } from 'rxjs/operators';
import { SHOPS } from '@dsh/app/shared/components/inputs/shop-field'; import { SHOPS } from '@dsh/app/shared/components/inputs/shop-field';
@ -32,10 +32,10 @@ export class PaymentSectionComponent implements OnInit {
navbarItemConfig$: Observable<NavbarItemConfig[]> = this.transloco navbarItemConfig$: Observable<NavbarItemConfig[]> = this.transloco
.selectTranslation('payment-section') .selectTranslation('payment-section')
.pipe(map(() => toNavbarItemConfig(this.getNavbarItemLabels()))); .pipe(map(() => toNavbarItemConfig(this.getNavbarItemLabels())));
activeSection$: Observable<string>; activeSection$ = defer(() => this.activeSectionChange$).pipe(map((s) => s.label));
noShops$: Observable<boolean> = this.realmShopsService.shops$.pipe(map((s) => s.length === 0)); noShops$: Observable<boolean> = this.realmShopsService.shops$.pipe(map((s) => s.length === 0));
private activeSectionChange$ = new Subject<NavbarItemConfig>(); private activeSectionChange$ = new ReplaySubject<NavbarItemConfig>();
private realmChange$ = new Subject<PaymentInstitution.RealmEnum>(); private realmChange$ = new Subject<PaymentInstitution.RealmEnum>();
private navigateToShops$ = new Subject<void>(); private navigateToShops$ = new Subject<void>();
@ -70,8 +70,6 @@ export class PaymentSectionComponent implements OnInit {
}), }),
); );
this.activeSection$ = this.activeSectionChange$.pipe(pluck('label'));
this.navigateToShops$.pipe(switchMapTo(this.realmService.realm$.pipe(first()))).subscribe( this.navigateToShops$.pipe(switchMapTo(this.realmService.realm$.pipe(first()))).subscribe(
(realm) => (realm) =>
void this.router.navigate(['../../', 'realm', realm, 'shops'], { void this.router.navigate(['../../', 'realm', realm, 'shops'], {

View File

@ -21,7 +21,10 @@
<dsh-details-item [title]="t('wallet')"> <dsh-details-item [title]="t('wallet')">
{{ withdrawal.wallet | walletDetails }} {{ withdrawal.wallet | walletDetails }}
</dsh-details-item> </dsh-details-item>
<dsh-details-item *ngIf="withdrawal.failure" [title]="t('error')" gdColumn="1/-1"> <dsh-details-item *ngIf="withdrawal.externalID" [title]="t('externalId')">
{{ withdrawal.externalID }}
</dsh-details-item>
<dsh-details-item *ngIf="withdrawal.failure" [title]="t('error')">
<div <div
*transloco=" *transloco="
let errors; let errors;

View File

@ -0,0 +1,6 @@
{
"language": {
"en": "English",
"ru": "Russian (Русский)"
}
}

View File

@ -0,0 +1,6 @@
{
"language": {
"en": "Английский (English)",
"ru": "Русский"
}
}

View File

@ -175,6 +175,7 @@
"withdrawals": { "withdrawals": {
"details": { "details": {
"error": "Error", "error": "Error",
"externalId": "External ID",
"fee": "Fee", "fee": "Fee",
"status": "Status", "status": "Status",
"wallet": "Wallet" "wallet": "Wallet"

View File

@ -175,6 +175,7 @@
"withdrawals": { "withdrawals": {
"details": { "details": {
"error": "Ошибка", "error": "Ошибка",
"externalId": "External ID",
"fee": "Комиссия", "fee": "Комиссия",
"status": "Статус", "status": "Статус",
"wallet": "Кошелек" "wallet": "Кошелек"