mirror of
https://github.com/valitydev/dashboard.git
synced 2024-11-06 02:25:23 +00:00
active org in url
This commit is contained in:
parent
2c6c392b82
commit
b4268b9ff1
@ -1,7 +1,6 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { IdGeneratorService } from '@rbkmoney/id-generator';
|
||||
import { Observable } from 'rxjs';
|
||||
import { first, switchMap } from 'rxjs/operators';
|
||||
|
||||
import {
|
||||
Claim,
|
||||
@ -11,105 +10,71 @@ import {
|
||||
Reason,
|
||||
StatusModificationUnit,
|
||||
} from '@dsh/api-codegen/claim-management';
|
||||
import { ContextService } from '@dsh/app/shared/services/context';
|
||||
import { mapResult, noContinuationToken } from '@dsh/operators';
|
||||
|
||||
export const CLAIM_STATUS = StatusModificationUnit.StatusEnum;
|
||||
|
||||
@Injectable()
|
||||
export class ClaimsService {
|
||||
constructor(
|
||||
private claimsService: APIClaimsService,
|
||||
private idGenerator: IdGeneratorService,
|
||||
private contextService: ContextService
|
||||
) {}
|
||||
constructor(private claimsService: APIClaimsService, private idGenerator: IdGeneratorService) {}
|
||||
|
||||
searchClaims(
|
||||
partyId: string,
|
||||
limit: number,
|
||||
claimStatuses?: StatusModificationUnit.StatusEnum[],
|
||||
claimID?: number,
|
||||
continuationToken?: string
|
||||
): Observable<InlineResponse200> {
|
||||
return this.contextService.organization$.pipe(
|
||||
first(),
|
||||
switchMap((organization) =>
|
||||
this.claimsService.searchClaims(
|
||||
this.idGenerator.shortUuid(),
|
||||
organization.id,
|
||||
limit,
|
||||
undefined,
|
||||
continuationToken,
|
||||
claimID,
|
||||
claimStatuses || Object.values(StatusModificationUnit.StatusEnum)
|
||||
)
|
||||
)
|
||||
return this.claimsService.searchClaims(
|
||||
this.idGenerator.shortUuid(),
|
||||
partyId,
|
||||
limit,
|
||||
undefined,
|
||||
continuationToken,
|
||||
claimID,
|
||||
claimStatuses || Object.values(StatusModificationUnit.StatusEnum)
|
||||
);
|
||||
}
|
||||
|
||||
search1000Claims(claimStatuses?: StatusModificationUnit.StatusEnum[]): Observable<Claim[]> {
|
||||
return this.searchClaims(1000, claimStatuses).pipe(noContinuationToken, mapResult);
|
||||
search1000Claims(partyId: string, claimStatuses?: StatusModificationUnit.StatusEnum[]): Observable<Claim[]> {
|
||||
return this.searchClaims(partyId, 1000, claimStatuses).pipe(noContinuationToken, mapResult);
|
||||
}
|
||||
|
||||
getClaimByID(claimID: number): Observable<Claim> {
|
||||
return this.contextService.organization$.pipe(
|
||||
first(),
|
||||
switchMap((organization) =>
|
||||
this.claimsService.getClaimByID(this.idGenerator.shortUuid(), organization.id, claimID)
|
||||
)
|
||||
getClaimByID(partyId: string, claimID: number): Observable<Claim> {
|
||||
return this.claimsService.getClaimByID(this.idGenerator.shortUuid(), partyId, claimID);
|
||||
}
|
||||
|
||||
createClaim(partyId: string, changeset: Modification[]): Observable<Claim> {
|
||||
return this.claimsService.createClaim(this.idGenerator.shortUuid(), partyId, changeset);
|
||||
}
|
||||
|
||||
updateClaimByID(
|
||||
partyId: string,
|
||||
claimID: number,
|
||||
claimRevision: number,
|
||||
changeset: Modification[]
|
||||
): Observable<void> {
|
||||
return this.claimsService.updateClaimByID(
|
||||
this.idGenerator.shortUuid(),
|
||||
partyId,
|
||||
claimID,
|
||||
claimRevision,
|
||||
changeset
|
||||
);
|
||||
}
|
||||
|
||||
createClaim(changeset: Modification[]): Observable<Claim> {
|
||||
return this.contextService.organization$.pipe(
|
||||
first(),
|
||||
switchMap((organization) =>
|
||||
this.claimsService.createClaim(this.idGenerator.shortUuid(), organization.id, changeset)
|
||||
)
|
||||
revokeClaimByID(partyId: string, claimID: number, claimRevision: number, reason: Reason): Observable<void> {
|
||||
return this.claimsService.revokeClaimByID(
|
||||
this.idGenerator.shortUuid(),
|
||||
partyId,
|
||||
claimID,
|
||||
claimRevision,
|
||||
undefined,
|
||||
reason
|
||||
);
|
||||
}
|
||||
|
||||
updateClaimByID(claimID: number, claimRevision: number, changeset: Modification[]): Observable<void> {
|
||||
return this.contextService.organization$.pipe(
|
||||
first(),
|
||||
switchMap((organization) =>
|
||||
this.claimsService.updateClaimByID(
|
||||
this.idGenerator.shortUuid(),
|
||||
organization.id,
|
||||
claimID,
|
||||
claimRevision,
|
||||
changeset
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
revokeClaimByID(claimID: number, claimRevision: number, reason: Reason): Observable<void> {
|
||||
return this.contextService.organization$.pipe(
|
||||
first(),
|
||||
switchMap((organization) =>
|
||||
this.claimsService.revokeClaimByID(
|
||||
this.idGenerator.shortUuid(),
|
||||
organization.id,
|
||||
claimID,
|
||||
claimRevision,
|
||||
undefined,
|
||||
reason
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
requestReviewClaimByID(claimID: number, claimRevision: number): Observable<void> {
|
||||
return this.contextService.organization$.pipe(
|
||||
first(),
|
||||
switchMap((organization) =>
|
||||
this.claimsService.requestReviewClaimByID(
|
||||
this.idGenerator.shortUuid(),
|
||||
organization.id,
|
||||
claimID,
|
||||
claimRevision
|
||||
)
|
||||
)
|
||||
);
|
||||
requestReviewClaimByID(partyId: string, claimID: number, claimRevision: number): Observable<void> {
|
||||
return this.claimsService.requestReviewClaimByID(this.idGenerator.shortUuid(), partyId, claimID, claimRevision);
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,2 @@
|
||||
<dsh-home>
|
||||
<dsh-sections *ngIf="bootstrapped$ | async"></dsh-sections>
|
||||
</dsh-home>
|
||||
<dsh-feedback fxHide.lt-md></dsh-feedback>
|
||||
<router-outlet></router-outlet>
|
||||
<dsh-yandex-metrika *ngIf="env.production"></dsh-yandex-metrika>
|
||||
|
@ -1,31 +1,12 @@
|
||||
import { Component, Inject, OnInit } from '@angular/core';
|
||||
import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy';
|
||||
import * as Sentry from '@sentry/angular';
|
||||
import { first } from 'rxjs/operators';
|
||||
import { Component, Inject, ChangeDetectionStrategy } from '@angular/core';
|
||||
|
||||
import { ENV, Env } from '../environments';
|
||||
import { BootstrapService } from './bootstrap.service';
|
||||
import { KeycloakTokenInfoService } from './shared';
|
||||
|
||||
@UntilDestroy()
|
||||
@Component({
|
||||
selector: 'dsh-root',
|
||||
templateUrl: 'app.component.html',
|
||||
providers: [BootstrapService],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class AppComponent implements OnInit {
|
||||
bootstrapped$ = this.bootstrapService.bootstrapped$;
|
||||
|
||||
constructor(
|
||||
private bootstrapService: BootstrapService,
|
||||
@Inject(ENV) public env: Env,
|
||||
private keycloakTokenInfoService: KeycloakTokenInfoService
|
||||
) {}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.bootstrapService.bootstrap();
|
||||
this.keycloakTokenInfoService.partyID$
|
||||
.pipe(first(), untilDestroyed(this))
|
||||
.subscribe((partyID) => Sentry.setUser({ id: partyID }));
|
||||
}
|
||||
export class AppComponent {
|
||||
constructor(@Inject(ENV) public env: Env) {}
|
||||
}
|
||||
|
@ -16,7 +16,6 @@ import { TRANSLOCO_CONFIG, TRANSLOCO_LOADER, TranslocoConfig, TranslocoModule }
|
||||
import * as Sentry from '@sentry/angular';
|
||||
|
||||
import { ErrorModule, KeycloakTokenInfoModule } from '@dsh/app/shared/services';
|
||||
import { ContextModule } from '@dsh/app/shared/services/context';
|
||||
import { QUERY_PARAMS_SERIALIZERS } from '@dsh/app/shared/services/query-params/utils/query-params-serializers';
|
||||
import { createDateRangeWithPresetSerializer } from '@dsh/components/filters/date-range-filter';
|
||||
import { SELECT_SEARCH_FIELD_OPTIONS } from '@dsh/components/form-controls/select-search-field';
|
||||
@ -41,7 +40,6 @@ import { TranslocoHttpLoaderService } from './transloco-http-loader.service';
|
||||
import { YandexMetrikaConfigService, YandexMetrikaModule } from './yandex-metrika';
|
||||
|
||||
@NgModule({
|
||||
declarations: [AppComponent],
|
||||
imports: [
|
||||
CommonModule,
|
||||
BrowserModule,
|
||||
@ -63,7 +61,6 @@ import { YandexMetrikaConfigService, YandexMetrikaModule } from './yandex-metrik
|
||||
IconsModule,
|
||||
KeycloakTokenInfoModule,
|
||||
FlexLayoutModule,
|
||||
ContextModule,
|
||||
],
|
||||
providers: [
|
||||
LanguageService,
|
||||
@ -133,6 +130,7 @@ import { YandexMetrikaConfigService, YandexMetrikaModule } from './yandex-metrik
|
||||
useValue: [createDateRangeWithPresetSerializer()],
|
||||
},
|
||||
],
|
||||
declarations: [AppComponent],
|
||||
bootstrap: [AppComponent],
|
||||
})
|
||||
export class AppModule {}
|
||||
|
@ -81,16 +81,21 @@ export class BootstrapService {
|
||||
}
|
||||
|
||||
private createTestShop(): Observable<boolean> {
|
||||
return this.claimsService
|
||||
.createClaim(
|
||||
createTestShopClaimChangeset(
|
||||
this.idGenerator.uuid(),
|
||||
this.idGenerator.uuid(),
|
||||
this.idGenerator.uuid(),
|
||||
this.idGenerator.uuid()
|
||||
return this.contextService.organization$.pipe(
|
||||
first(),
|
||||
switchMap((org) =>
|
||||
this.claimsService.createClaim(
|
||||
org.id,
|
||||
createTestShopClaimChangeset(
|
||||
this.idGenerator.uuid(),
|
||||
this.idGenerator.uuid(),
|
||||
this.idGenerator.uuid(),
|
||||
this.idGenerator.uuid()
|
||||
)
|
||||
)
|
||||
)
|
||||
.pipe(mapTo(true));
|
||||
),
|
||||
mapTo(true)
|
||||
);
|
||||
}
|
||||
|
||||
private initContext(): Observable<boolean> {
|
||||
|
@ -18,7 +18,7 @@
|
||||
dsh-button
|
||||
color="accent"
|
||||
(click)="confirm()"
|
||||
[disabled]="!selectedOrganization || selectedOrganization.id === (contextOrganization$ | async)?.id"
|
||||
[disabled]="!selectedOrganization || selectedOrganization.id === organization.id"
|
||||
>
|
||||
{{ t('confirm') }}
|
||||
</button>
|
||||
|
@ -1,14 +1,11 @@
|
||||
import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core';
|
||||
import { MatDialogRef } from '@angular/material/dialog';
|
||||
import { Router } from '@angular/router';
|
||||
import { ChangeDetectionStrategy, Component, OnInit, Inject } from '@angular/core';
|
||||
import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
|
||||
import { untilDestroyed, UntilDestroy } from '@ngneat/until-destroy';
|
||||
import { combineLatest } from 'rxjs';
|
||||
import { first, map } from 'rxjs/operators';
|
||||
|
||||
import { Organization } from '@dsh/api-codegen/organizations';
|
||||
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 { FetchOrganizationsService } from '@dsh/app/shared/services/fetch-organizations';
|
||||
|
||||
const DISPLAYED_COUNT = 5;
|
||||
@ -26,24 +23,22 @@ export class SelectActiveOrganizationDialogComponent implements OnInit {
|
||||
displayedCount = DISPLAYED_COUNT;
|
||||
selectedOrganization: Organization;
|
||||
isLoading$ = this.fetchOrganizationsService.doAction$;
|
||||
contextOrganization$ = this.contextService.organization$;
|
||||
|
||||
constructor(
|
||||
private dialogRef: MatDialogRef<
|
||||
SelectActiveOrganizationDialogComponent,
|
||||
BaseDialogResponseStatus | Organization
|
||||
>,
|
||||
private fetchOrganizationsService: FetchOrganizationsService,
|
||||
private router: Router,
|
||||
private contextService: ContextService
|
||||
@Inject(MAT_DIALOG_DATA) public organization: Organization,
|
||||
private fetchOrganizationsService: FetchOrganizationsService
|
||||
) {}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.fetchOrganizationsService.search();
|
||||
combineLatest([this.organizations$, this.contextService.organization$])
|
||||
this.organizations$
|
||||
.pipe(
|
||||
first(),
|
||||
map(([orgs, activeOrg]) => orgs.find((org) => org.id === activeOrg.id)),
|
||||
map((organizations) => organizations.find((org) => org.id === this.organization.id)),
|
||||
untilDestroyed(this)
|
||||
)
|
||||
.subscribe((organization) => (this.selectedOrganization = organization));
|
||||
@ -51,7 +46,6 @@ export class SelectActiveOrganizationDialogComponent implements OnInit {
|
||||
|
||||
confirm(): void {
|
||||
this.dialogRef.close(this.selectedOrganization);
|
||||
void this.router.navigate(['/']);
|
||||
}
|
||||
|
||||
close(): void {
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { ChangeDetectionStrategy, Component, Output, EventEmitter, Inject } from '@angular/core';
|
||||
import { MatDialog } from '@angular/material/dialog';
|
||||
import { Router } from '@angular/router';
|
||||
import { filter } from 'rxjs/operators';
|
||||
import { filter, first, switchMap } from 'rxjs/operators';
|
||||
|
||||
import { Organization } from '@dsh/api-codegen/organizations';
|
||||
import { DIALOG_CONFIG, DialogConfig } from '@dsh/app/sections/tokens';
|
||||
@ -57,13 +57,20 @@ export class UserComponent {
|
||||
|
||||
selectActiveOrg(): void {
|
||||
this.selected.emit();
|
||||
this.dialog
|
||||
.open<SelectActiveOrganizationDialogComponent, void, BaseDialogResponseStatus | Organization>(
|
||||
SelectActiveOrganizationDialogComponent,
|
||||
this.dialogConfig.medium
|
||||
this.contextService.organization$
|
||||
.pipe(
|
||||
first(),
|
||||
switchMap((organization) =>
|
||||
this.dialog
|
||||
.open<
|
||||
SelectActiveOrganizationDialogComponent,
|
||||
Organization,
|
||||
BaseDialogResponseStatus | Organization
|
||||
>(SelectActiveOrganizationDialogComponent, { ...this.dialogConfig.medium, data: organization })
|
||||
.afterClosed()
|
||||
),
|
||||
filter((res) => !Object.values(BaseDialogResponseStatus).includes(res as BaseDialogResponseStatus))
|
||||
)
|
||||
.afterClosed()
|
||||
.pipe(filter((res) => !Object.values(BaseDialogResponseStatus).includes(res as BaseDialogResponseStatus)))
|
||||
.subscribe((org: Organization) => {
|
||||
this.contextService.switchOrganization(org.id);
|
||||
});
|
||||
|
@ -1,20 +1,18 @@
|
||||
<div *ngIf="routerNavigationEnd$ | async">
|
||||
<dsh-welcome-image *ngIf="hasBackground"></dsh-welcome-image>
|
||||
<ng-container *ngTemplateOutlet="(isXSmallSmall$ | async) ? mobile : laptop"> </ng-container>
|
||||
</div>
|
||||
<dsh-welcome-image *ngIf="hasBackground$ | async"></dsh-welcome-image>
|
||||
<ng-container *ngTemplateOutlet="(isXSmallSmall$ | async) ? mobile : laptop"> </ng-container>
|
||||
|
||||
<ng-template #content>
|
||||
<ng-content></ng-content>
|
||||
</ng-template>
|
||||
|
||||
<ng-template #mobile>
|
||||
<dsh-mobile-grid [inverted]="hasBackground" [logoName]="logoName">
|
||||
<dsh-mobile-grid [inverted]="hasBackground$ | async" [logoName]="logoName">
|
||||
<ng-container *ngTemplateOutlet="content"></ng-container>
|
||||
</dsh-mobile-grid>
|
||||
</ng-template>
|
||||
|
||||
<ng-template #laptop>
|
||||
<dsh-laptop-grid [inverted]="hasBackground" [logoName]="logoName">
|
||||
<dsh-laptop-grid [inverted]="hasBackground$ | async" [logoName]="logoName">
|
||||
<ng-container *ngTemplateOutlet="content"></ng-container>
|
||||
</dsh-laptop-grid>
|
||||
</ng-template>
|
||||
|
@ -1,9 +1,10 @@
|
||||
import { BreakpointObserver, Breakpoints } from '@angular/cdk/layout';
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { NavigationEnd, Router, RouterEvent } from '@angular/router';
|
||||
import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy';
|
||||
import { Observable } from 'rxjs';
|
||||
import { filter, map, pluck, take } from 'rxjs/operators';
|
||||
import { Component } from '@angular/core';
|
||||
import { Router, ActivatedRoute, NavigationEnd } from '@angular/router';
|
||||
import { UntilDestroy } from '@ngneat/until-destroy';
|
||||
import { pluck, filter, map, startWith, distinctUntilChanged } from 'rxjs/operators';
|
||||
|
||||
import { shareReplayRefCount } from '@dsh/operators';
|
||||
|
||||
import { ThemeManager } from '../theme-manager';
|
||||
|
||||
@ -12,34 +13,25 @@ import { ThemeManager } from '../theme-manager';
|
||||
selector: 'dsh-home',
|
||||
templateUrl: 'home.component.html',
|
||||
})
|
||||
export class HomeComponent implements OnInit {
|
||||
routerNavigationEnd$: Observable<boolean>;
|
||||
isXSmallSmall$: Observable<boolean>;
|
||||
export class HomeComponent {
|
||||
isXSmallSmall$ = this.breakpointObserver.observe([Breakpoints.XSmall, Breakpoints.Small]).pipe(pluck('matches'));
|
||||
hasBackground$ = this.router.events.pipe(
|
||||
filter((event) => event instanceof NavigationEnd),
|
||||
startWith(null),
|
||||
map(() => /^\/organization\/[\w-]+$/.test(this.router.url) && this.themeManager.isMainBackgroundImages),
|
||||
distinctUntilChanged(),
|
||||
shareReplayRefCount()
|
||||
);
|
||||
|
||||
constructor(
|
||||
private router: Router,
|
||||
private route: ActivatedRoute,
|
||||
// need to create class when home component was init
|
||||
private themeManager: ThemeManager,
|
||||
private breakpointObserver: BreakpointObserver
|
||||
) {}
|
||||
|
||||
get hasBackground(): boolean {
|
||||
return this.router.url === '/' && this.themeManager.isMainBackgroundImages;
|
||||
}
|
||||
|
||||
get logoName(): string {
|
||||
return this.themeManager.logoName;
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.routerNavigationEnd$ = this.router.events.pipe(
|
||||
filter((event: RouterEvent) => event instanceof NavigationEnd),
|
||||
map(() => true),
|
||||
take(1),
|
||||
untilDestroyed(this)
|
||||
);
|
||||
this.isXSmallSmall$ = this.breakpointObserver
|
||||
.observe([Breakpoints.XSmall, Breakpoints.Small])
|
||||
.pipe(pluck('matches'));
|
||||
}
|
||||
}
|
||||
|
@ -11,7 +11,7 @@
|
||||
<a
|
||||
*ngFor="let link of sectionLinks$ | async"
|
||||
mat-tab-link
|
||||
[routerLink]="link.path"
|
||||
[routerLink]="'/organization/' + (organization$ | async)?.id + link.path"
|
||||
routerLinkActive
|
||||
[routerLinkActiveOptions]="{ exact: link?.exact }"
|
||||
#rla="routerLinkActive"
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { ChangeDetectionStrategy, Component, Input } from '@angular/core';
|
||||
|
||||
import { ContextService } from '@dsh/app/shared/services/context';
|
||||
import { SectionsLinksService } from '@dsh/app/shared/services/sections-links';
|
||||
import { coerceBoolean } from '@dsh/utils';
|
||||
|
||||
@ -14,6 +15,7 @@ export class ToolbarComponent {
|
||||
@Input() logoName: string;
|
||||
|
||||
sectionLinks$ = this.sectionsLinksService.sectionLinks$;
|
||||
organization$ = this.contextService.organization$;
|
||||
|
||||
constructor(private sectionsLinksService: SectionsLinksService) {}
|
||||
constructor(private sectionsLinksService: SectionsLinksService, private contextService: ContextService) {}
|
||||
}
|
||||
|
@ -4,9 +4,10 @@ import { MatSnackBar } from '@angular/material/snack-bar';
|
||||
import { TranslocoService } from '@ngneat/transloco';
|
||||
import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy';
|
||||
import { BehaviorSubject, Observable, of, Subject } from 'rxjs';
|
||||
import { catchError, filter, map, pluck, shareReplay, switchMap, tap } from 'rxjs/operators';
|
||||
import { catchError, filter, map, pluck, shareReplay, switchMap, tap, withLatestFrom } from 'rxjs/operators';
|
||||
|
||||
import { ClaimsService } from '@dsh/api/claims';
|
||||
import { ContextService } from '@dsh/app/shared/services/context';
|
||||
import { ConfirmActionDialogComponent } from '@dsh/components/popups';
|
||||
|
||||
import { UiError } from '../../ui-error';
|
||||
@ -39,7 +40,8 @@ export class ReviewClaimService {
|
||||
private receiveClaimService: ReceiveClaimService,
|
||||
private dialog: MatDialog,
|
||||
private snackBar: MatSnackBar,
|
||||
private transloco: TranslocoService
|
||||
private transloco: TranslocoService,
|
||||
private contextService: ContextService
|
||||
) {
|
||||
this.reviewClaim$
|
||||
.pipe(
|
||||
@ -61,8 +63,9 @@ export class ReviewClaimService {
|
||||
)
|
||||
),
|
||||
switchMap(() => this.routeParamClaimService.claim$),
|
||||
switchMap(({ id, revision }) =>
|
||||
this.claimsApiService.requestReviewClaimByID(id, revision).pipe(
|
||||
withLatestFrom(this.contextService.organization$),
|
||||
switchMap(([{ id, revision }, org]) =>
|
||||
this.claimsApiService.requestReviewClaimByID(org.id, id, revision).pipe(
|
||||
catchError((ex) => {
|
||||
this.progress$.next(false);
|
||||
console.error(ex);
|
||||
|
@ -4,9 +4,10 @@ import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
|
||||
import { progress } from '@rbkmoney/utils';
|
||||
import get from 'lodash-es/get';
|
||||
import { BehaviorSubject, Observable, of, Subject } from 'rxjs';
|
||||
import { catchError, filter, pluck, switchMap, tap } from 'rxjs/operators';
|
||||
import { catchError, filter, pluck, switchMap, tap, withLatestFrom } from 'rxjs/operators';
|
||||
|
||||
import { ClaimsService } from '@dsh/api/claims';
|
||||
import { ContextService } from '@dsh/app/shared/services/context';
|
||||
|
||||
import { UiError } from '../../../ui-error';
|
||||
import { RevokeClaimDialogComponent } from './revoke-claim-dialog.component';
|
||||
@ -27,7 +28,8 @@ export class RevokeClaimDialogService {
|
||||
private dialogRef: MatDialogRef<RevokeClaimDialogComponent, 'cancel' | 'revoked'>,
|
||||
private claimsApiService: ClaimsService,
|
||||
private fb: FormBuilder,
|
||||
@Inject(MAT_DIALOG_DATA) private data: { claimId: number; revision: number }
|
||||
@Inject(MAT_DIALOG_DATA) private data: { claimId: number; revision: number },
|
||||
private contextService: ContextService
|
||||
) {
|
||||
this.form = this.fb.group({
|
||||
reason: ['', [Validators.required, Validators.maxLength(1000)]],
|
||||
@ -35,8 +37,9 @@ export class RevokeClaimDialogService {
|
||||
this.revoke$
|
||||
.pipe(
|
||||
tap(() => this.error$.next({ hasError: false })),
|
||||
switchMap((reason) =>
|
||||
this.claimsApiService.revokeClaimByID(this.data.claimId, this.data.revision, reason).pipe(
|
||||
withLatestFrom(this.contextService.organization$),
|
||||
switchMap(([reason, org]) =>
|
||||
this.claimsApiService.revokeClaimByID(org.id, this.data.claimId, this.data.revision, reason).pipe(
|
||||
catchError((ex) => {
|
||||
console.error(ex);
|
||||
const error = { hasError: true, code: 'revokeClaimByIDFailed' };
|
||||
|
@ -1,15 +1,20 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { combineLatest } from 'rxjs';
|
||||
import { pluck, switchMap } from 'rxjs/operators';
|
||||
|
||||
import { ClaimsService } from '@dsh/api/claims';
|
||||
import { ContextService } from '@dsh/app/shared/services/context';
|
||||
|
||||
@Injectable()
|
||||
export class RouteParamClaimService {
|
||||
claim$ = this.route.params.pipe(
|
||||
pluck('claimId'),
|
||||
switchMap((id) => this.claimsService.getClaimByID(id))
|
||||
claim$ = combineLatest([this.contextService.organization$, this.route.params.pipe(pluck('claimId'))]).pipe(
|
||||
switchMap(([org, id]) => this.claimsService.getClaimByID(org.id, id))
|
||||
);
|
||||
|
||||
constructor(private route: ActivatedRoute, private claimsService: ClaimsService) {}
|
||||
constructor(
|
||||
private route: ActivatedRoute,
|
||||
private claimsService: ClaimsService,
|
||||
private contextService: ContextService
|
||||
) {}
|
||||
}
|
||||
|
@ -1,12 +1,13 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { MatSnackBar } from '@angular/material/snack-bar';
|
||||
import { TranslocoService } from '@ngneat/transloco';
|
||||
import { BehaviorSubject, combineLatest, Observable, of, Subject } from 'rxjs';
|
||||
import { catchError, filter, pluck, share, switchMap, tap } from 'rxjs/operators';
|
||||
import { BehaviorSubject, Observable, of, Subject } from 'rxjs';
|
||||
import { catchError, filter, pluck, share, switchMap, tap, withLatestFrom } from 'rxjs/operators';
|
||||
|
||||
import { FileModification } from '@dsh/api-codegen/claim-management';
|
||||
import { Conversation } from '@dsh/api-codegen/messages';
|
||||
import { ClaimsService } from '@dsh/api/claims';
|
||||
import { ContextService } from '@dsh/app/shared/services/context';
|
||||
|
||||
import { progress } from '../../../../custom-operators';
|
||||
import { UiError } from '../../../ui-error';
|
||||
@ -33,14 +34,15 @@ export class UpdateClaimService {
|
||||
private routeParamClaimService: RouteParamClaimService,
|
||||
private claimApiService: ClaimsService,
|
||||
private snackBar: MatSnackBar,
|
||||
private transloco: TranslocoService
|
||||
private transloco: TranslocoService,
|
||||
private contextService: ContextService
|
||||
) {
|
||||
const updated$ = this.updateBy$.pipe(
|
||||
tap(() => this.error$.next({ hasError: false })),
|
||||
toChangeset,
|
||||
switchMap((changeset) => combineLatest([of(changeset), this.routeParamClaimService.claim$])),
|
||||
switchMap(([changeset, { id, revision }]) =>
|
||||
this.claimApiService.updateClaimByID(id, revision, changeset).pipe(
|
||||
withLatestFrom(this.routeParamClaimService.claim$, this.contextService.organization$),
|
||||
switchMap(([changeset, { id, revision }, org]) =>
|
||||
this.claimApiService.updateClaimByID(org.id, id, revision, changeset).pipe(
|
||||
catchError((ex) => {
|
||||
console.error(ex);
|
||||
const error = { hasError: true, code: 'updateClaimByIDFailed' };
|
||||
|
@ -3,10 +3,11 @@ import { MatSnackBar } from '@angular/material/snack-bar';
|
||||
import { TranslocoService } from '@ngneat/transloco';
|
||||
import { FetchResult, PartialFetcher } from '@rbkmoney/partial-fetcher';
|
||||
import { Observable } from 'rxjs';
|
||||
import { shareReplay } from 'rxjs/operators';
|
||||
import { shareReplay, first, switchMap } from 'rxjs/operators';
|
||||
|
||||
import { Claim } from '@dsh/api-codegen/claim-management/swagger-codegen';
|
||||
import { ClaimsService } from '@dsh/api/claims';
|
||||
import { ContextService } from '@dsh/app/shared/services/context';
|
||||
import { booleanDebounceTime, mapToTimestamp } from '@dsh/operators';
|
||||
|
||||
import { ClaimsSearchFiltersSearchParams } from '../../claims-search-filters/claims-search-filters-search-params';
|
||||
@ -21,7 +22,8 @@ export class FetchClaimsService extends PartialFetcher<Claim, ClaimsSearchFilter
|
||||
constructor(
|
||||
private claimsService: ClaimsService,
|
||||
private snackBar: MatSnackBar,
|
||||
private transloco: TranslocoService
|
||||
private transloco: TranslocoService,
|
||||
private contextService: ContextService
|
||||
) {
|
||||
super();
|
||||
this.errors$.subscribe(() => {
|
||||
@ -34,11 +36,17 @@ export class FetchClaimsService extends PartialFetcher<Claim, ClaimsSearchFilter
|
||||
params: ClaimsSearchFiltersSearchParams,
|
||||
continuationToken: string
|
||||
): Observable<FetchResult<Claim>> {
|
||||
return this.claimsService.searchClaims(
|
||||
this.searchLimit,
|
||||
params.claimStatuses,
|
||||
params.claimID,
|
||||
continuationToken
|
||||
return this.contextService.organization$.pipe(
|
||||
first(),
|
||||
switchMap(({ id }) =>
|
||||
this.claimsService.searchClaims(
|
||||
id,
|
||||
this.searchLimit,
|
||||
params.claimStatuses,
|
||||
params.claimID,
|
||||
continuationToken
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -7,8 +7,8 @@ import { TranslocoService } from '@ngneat/transloco';
|
||||
import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy';
|
||||
import { IdGeneratorService } from '@rbkmoney/id-generator';
|
||||
import isNil from 'lodash-es/isNil';
|
||||
import { combineLatest, Observable, of, Subject, throwError } from 'rxjs';
|
||||
import { catchError, filter, map, mapTo, pluck, switchMap } from 'rxjs/operators';
|
||||
import { combineLatest, Observable, of, Subject, throwError, EMPTY } from 'rxjs';
|
||||
import { catchError, filter, map, mapTo, pluck, switchMap, withLatestFrom } from 'rxjs/operators';
|
||||
|
||||
import { OrgType, PartyContent, ReqResponse } from '@dsh/api-codegen/aggr-proxy';
|
||||
import { Claim } from '@dsh/api-codegen/claim-management';
|
||||
@ -21,6 +21,7 @@ import {
|
||||
} from '@dsh/api/claims';
|
||||
import { KonturFocusService } from '@dsh/api/kontur-focus';
|
||||
import { QuestionaryService } from '@dsh/api/questionary';
|
||||
import { ContextService } from '@dsh/app/shared/services/context';
|
||||
import { ConfirmActionDialogComponent } from '@dsh/components/popups';
|
||||
import { shareReplayRefCount } from '@dsh/operators';
|
||||
|
||||
@ -39,11 +40,11 @@ export class CompanySearchService {
|
||||
switchMap(({ claimID }) => of<number>(isNil(claimID) ? null : Number(claimID))),
|
||||
shareReplayRefCount()
|
||||
);
|
||||
private claim$ = this.claimID$.pipe(
|
||||
switchMap((claimID) =>
|
||||
private claim$ = combineLatest([this.contextService.organization$, this.claimID$]).pipe(
|
||||
switchMap(([org, claimID]) =>
|
||||
isNil(claimID)
|
||||
? of<Claim>(null)
|
||||
: this.claimsService.getClaimByID(claimID).pipe(catchError(() => of<Claim>(null)))
|
||||
: this.claimsService.getClaimByID(org.id, claimID).pipe(catchError(() => of<Claim>(null)))
|
||||
),
|
||||
shareReplayRefCount()
|
||||
);
|
||||
@ -59,7 +60,8 @@ export class CompanySearchService {
|
||||
private konturFocusService: KonturFocusService,
|
||||
private keycloakService: KeycloakService,
|
||||
private idGenerator: IdGeneratorService,
|
||||
private route: ActivatedRoute
|
||||
private route: ActivatedRoute,
|
||||
private contextService: ContextService
|
||||
) {
|
||||
this.leaveOnboarding$
|
||||
.pipe(
|
||||
@ -69,19 +71,23 @@ export class CompanySearchService {
|
||||
)
|
||||
.subscribe(() => void this.router.navigate(['/']));
|
||||
combineLatest(this.claim$, this.claimID$)
|
||||
.pipe(untilDestroyed(this))
|
||||
.subscribe(([claim, claimID]) => {
|
||||
if (
|
||||
(claimID && !claim) ||
|
||||
(claim &&
|
||||
!claim.changeset.every(
|
||||
(c) =>
|
||||
isClaimModification(c.modification) &&
|
||||
isExternalInfoModificationUnit(c.modification.claimModificationType)
|
||||
))
|
||||
)
|
||||
void this.router.navigate(['./onboarding']);
|
||||
});
|
||||
.pipe(
|
||||
switchMap(([claim, claimID]) => {
|
||||
if (
|
||||
(claimID && !claim) ||
|
||||
(claim &&
|
||||
!claim.changeset.every(
|
||||
(c) =>
|
||||
isClaimModification(c.modification) &&
|
||||
isExternalInfoModificationUnit(c.modification.claimModificationType)
|
||||
))
|
||||
)
|
||||
return this.contextService.navigate(['onboarding']);
|
||||
return EMPTY;
|
||||
}),
|
||||
untilDestroyed(this)
|
||||
)
|
||||
.subscribe();
|
||||
}
|
||||
|
||||
isKnownOrgType({ orgType }: PartyContent): boolean {
|
||||
@ -94,11 +100,14 @@ export class CompanySearchService {
|
||||
const defaultEmail = this.keycloakService.getUsername();
|
||||
const questionaryData: QuestionaryData = { ...data, contactInfo: { email: defaultEmail, ...data.contactInfo } };
|
||||
return this.claim$.pipe(
|
||||
switchMap((claim) =>
|
||||
withLatestFrom(this.contextService.organization$),
|
||||
switchMap(([claim, org]) =>
|
||||
claim
|
||||
? this.claimsService.updateClaimByID(claim.id, claim.revision, changeset).pipe(mapTo(claim.id))
|
||||
? this.claimsService
|
||||
.updateClaimByID(org.id, claim.id, claim.revision, changeset)
|
||||
.pipe(mapTo(claim.id))
|
||||
: this.questionaryService.saveQuestionary(documentID, questionaryData).pipe(
|
||||
switchMap(() => this.claimsService.createClaim(changeset)),
|
||||
switchMap(() => this.claimsService.createClaim(org.id, changeset)),
|
||||
pluck('id')
|
||||
)
|
||||
),
|
||||
|
@ -4,17 +4,22 @@ import { BehaviorSubject, combineLatest, defer } from 'rxjs';
|
||||
import { shareReplay, switchMap } from 'rxjs/operators';
|
||||
|
||||
import { ClaimsService } from '@dsh/api/claims';
|
||||
import { ContextService } from '@dsh/app/shared/services/context';
|
||||
|
||||
@Injectable()
|
||||
export class ClaimService {
|
||||
claim$ = combineLatest([this.route.params, defer(() => this.loadClaim$)]).pipe(
|
||||
switchMap(([{ claimID }]) => this.claimsService.getClaimByID(claimID)),
|
||||
claim$ = combineLatest([this.route.params, this.contextService.organization$, defer(() => this.loadClaim$)]).pipe(
|
||||
switchMap(([{ claimID }, org]) => this.claimsService.getClaimByID(org.id, claimID)),
|
||||
shareReplay(1)
|
||||
);
|
||||
|
||||
private loadClaim$ = new BehaviorSubject<void>(undefined);
|
||||
|
||||
constructor(private route: ActivatedRoute, private claimsService: ClaimsService) {}
|
||||
constructor(
|
||||
private route: ActivatedRoute,
|
||||
private claimsService: ClaimsService,
|
||||
private contextService: ContextService
|
||||
) {}
|
||||
|
||||
reloadClaim(): void {
|
||||
this.loadClaim$.next();
|
||||
|
@ -9,6 +9,7 @@ import { map, pluck, share, switchMap, withLatestFrom } from 'rxjs/operators';
|
||||
import { FileModification, FileModificationUnit } from '@dsh/api-codegen/claim-management';
|
||||
import { QuestionaryData } from '@dsh/api-codegen/questionary';
|
||||
import { ClaimsService, createFileModificationUnit, takeFileModificationUnits } from '@dsh/api/claims';
|
||||
import { ContextService } from '@dsh/app/shared/services/context';
|
||||
import { filterError, filterPayload, replaceError } from '@dsh/operators';
|
||||
|
||||
import { ClaimService } from '../../claim';
|
||||
@ -36,14 +37,15 @@ export class UploadDocumentsService extends QuestionaryFormService {
|
||||
private claimService: ClaimService,
|
||||
private claimsService: ClaimsService,
|
||||
private snackBar: MatSnackBar,
|
||||
private transloco: TranslocoService
|
||||
private transloco: TranslocoService,
|
||||
private contextService: ContextService
|
||||
) {
|
||||
super(questionaryStateService, validityService, validationCheckService);
|
||||
const uploadedFilesWithError$ = this.filesUploaded$.pipe(
|
||||
map((fileIds) => fileIds.map((id) => createFileModificationUnit(id))),
|
||||
withLatestFrom(this.claimService.claim$),
|
||||
switchMap(([changeset, { id, revision }]) =>
|
||||
this.claimsService.updateClaimByID(id, revision, changeset).pipe(replaceError)
|
||||
withLatestFrom(this.claimService.claim$, this.contextService.organization$),
|
||||
switchMap(([changeset, { id, revision }, org]) =>
|
||||
this.claimsService.updateClaimByID(org.id, id, revision, changeset).pipe(replaceError)
|
||||
),
|
||||
share()
|
||||
);
|
||||
@ -51,9 +53,9 @@ export class UploadDocumentsService extends QuestionaryFormService {
|
||||
map((unit) => [
|
||||
createFileModificationUnit(unit.fileId, FileModification.FileModificationTypeEnum.FileDeleted),
|
||||
]),
|
||||
withLatestFrom(this.claimService.claim$),
|
||||
switchMap(([changeset, { id, revision }]) =>
|
||||
this.claimsService.updateClaimByID(id, revision, changeset).pipe(replaceError)
|
||||
withLatestFrom(this.claimService.claim$, this.contextService.organization$),
|
||||
switchMap(([changeset, { id, revision }, org]) =>
|
||||
this.claimsService.updateClaimByID(org.id, id, revision, changeset).pipe(replaceError)
|
||||
),
|
||||
share()
|
||||
);
|
||||
|
@ -3,9 +3,10 @@ import { MatDialog } from '@angular/material/dialog';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy';
|
||||
import { combineLatest, Observable, Subject } from 'rxjs';
|
||||
import { filter, map, pluck, shareReplay, switchMap, switchMapTo } from 'rxjs/operators';
|
||||
import { filter, map, pluck, shareReplay, switchMap, switchMapTo, withLatestFrom } from 'rxjs/operators';
|
||||
|
||||
import { ClaimsService } from '@dsh/api/claims';
|
||||
import { ContextService } from '@dsh/app/shared/services/context';
|
||||
import { ConfirmActionDialogComponent } from '@dsh/components/popups';
|
||||
|
||||
import { QuestionaryStateService } from '../questionary-state.service';
|
||||
@ -32,7 +33,8 @@ export class StepCardService {
|
||||
private claimsService: ClaimsService,
|
||||
private dialog: MatDialog,
|
||||
private route: ActivatedRoute,
|
||||
private validityService: ValidityService
|
||||
private validityService: ValidityService,
|
||||
private contextService: ContextService
|
||||
) {
|
||||
const claimID$ = this.route.params.pipe(pluck('claimID'));
|
||||
combineLatest([this.stepFlowService.stepFlow$, this.selectStepFlowIndex$])
|
||||
@ -49,8 +51,13 @@ export class StepCardService {
|
||||
switchMap(() => this.dialog.open(ConfirmActionDialogComponent).afterClosed()),
|
||||
filter((r) => r === 'confirm'),
|
||||
switchMapTo(claimID$),
|
||||
switchMap((claimID) => this.claimsService.getClaimByID(claimID)),
|
||||
switchMap(({ id, revision }) => this.claimsService.requestReviewClaimByID(id, revision)),
|
||||
withLatestFrom(this.contextService.organization$),
|
||||
switchMap(([claimID, org]) =>
|
||||
this.claimsService.getClaimByID(org.id, claimID).pipe(map((claim) => [claim, org.id] as const))
|
||||
),
|
||||
switchMap(([{ id, revision }, orgId]) =>
|
||||
this.claimsService.requestReviewClaimByID(orgId, id, revision)
|
||||
),
|
||||
switchMapTo(claimID$),
|
||||
untilDestroyed(this)
|
||||
)
|
||||
|
@ -1,2 +1 @@
|
||||
export * from './sections.module';
|
||||
export * from './sections.component';
|
||||
|
@ -2,10 +2,11 @@ import { Injectable } from '@angular/core';
|
||||
import { MatSnackBar } from '@angular/material/snack-bar';
|
||||
import { TranslocoService } from '@ngneat/transloco';
|
||||
import { combineLatest, Observable } from 'rxjs';
|
||||
import { pluck, shareReplay } from 'rxjs/operators';
|
||||
import { pluck, shareReplay, switchMap } from 'rxjs/operators';
|
||||
|
||||
import { ClaimsService, CLAIM_STATUS } from '@dsh/api/claims';
|
||||
import { ApiShopsService } from '@dsh/api/shop';
|
||||
import { ContextService } from '@dsh/app/shared/services/context';
|
||||
import { booleanDelay, takeError } from '@dsh/operators';
|
||||
|
||||
import { ActionBtnContent, TestEnvBtnContent } from './content-config';
|
||||
@ -22,11 +23,19 @@ export class PaymentsService {
|
||||
private shopService: ApiShopsService,
|
||||
private claimService: ClaimsService,
|
||||
private snackBar: MatSnackBar,
|
||||
private transloco: TranslocoService
|
||||
private transloco: TranslocoService,
|
||||
private contextService: ContextService
|
||||
) {
|
||||
const claims = this.claimService
|
||||
.search1000Claims([CLAIM_STATUS.Pending, CLAIM_STATUS.PendingAcceptance, CLAIM_STATUS.Review])
|
||||
.pipe(shareReplay(1));
|
||||
const claims = this.contextService.organization$.pipe(
|
||||
switchMap(({ id }) =>
|
||||
this.claimService.search1000Claims(id, [
|
||||
CLAIM_STATUS.Pending,
|
||||
CLAIM_STATUS.PendingAcceptance,
|
||||
CLAIM_STATUS.Review,
|
||||
])
|
||||
),
|
||||
shareReplay(1)
|
||||
);
|
||||
const contentConfig = toContentConf(this.shopService.shops$, claims);
|
||||
this.actionBtnContent$ = contentConfig.pipe(pluck('actionBtnContent'));
|
||||
this.testEnvBtnContent$ = contentConfig.pipe(pluck('testEnvBtnContent'));
|
||||
|
@ -1,26 +1,44 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { RouterModule, Routes } from '@angular/router';
|
||||
|
||||
import { SectionsComponent } from './sections.component';
|
||||
|
||||
const ROUTES: Routes = [
|
||||
{
|
||||
path: 'organization',
|
||||
pathMatch: 'full',
|
||||
redirectTo: 'organization/',
|
||||
},
|
||||
{
|
||||
path: '',
|
||||
loadChildren: () => import('./landing').then((m) => m.LandingModule),
|
||||
pathMatch: 'full',
|
||||
redirectTo: 'organization/',
|
||||
},
|
||||
{
|
||||
path: 'claim-section',
|
||||
loadChildren: () => import('./claim-section').then((m) => m.ClaimSectionModule),
|
||||
},
|
||||
{
|
||||
path: 'payment-section',
|
||||
loadChildren: () => import('./payment-section').then((m) => m.PaymentSectionModule),
|
||||
},
|
||||
{
|
||||
path: 'wallet-section',
|
||||
loadChildren: () => import('./wallet-section').then((m) => m.WalletSectionModule),
|
||||
},
|
||||
{
|
||||
path: 'organization-section',
|
||||
loadChildren: () => import('./organization-section').then((m) => m.OrginizationSectionModule),
|
||||
path: 'organization/:organizationId',
|
||||
component: SectionsComponent,
|
||||
children: [
|
||||
{
|
||||
path: '',
|
||||
loadChildren: () => import('./landing').then((m) => m.LandingModule),
|
||||
},
|
||||
{
|
||||
path: 'claim-section',
|
||||
loadChildren: () => import('./claim-section').then((m) => m.ClaimSectionModule),
|
||||
},
|
||||
{
|
||||
path: 'payment-section',
|
||||
loadChildren: () => import('./payment-section').then((m) => m.PaymentSectionModule),
|
||||
},
|
||||
{
|
||||
path: 'wallet-section',
|
||||
loadChildren: () => import('./wallet-section').then((m) => m.WalletSectionModule),
|
||||
},
|
||||
{
|
||||
path: 'organization-section',
|
||||
loadChildren: () => import('./organization-section').then((m) => m.OrginizationSectionModule),
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: '**',
|
||||
|
4
src/app/sections/sections.component.html
Normal file
4
src/app/sections/sections.component.html
Normal file
@ -0,0 +1,4 @@
|
||||
<dsh-home>
|
||||
<router-outlet *ngIf="bootstrapped$ | async"></router-outlet>
|
||||
</dsh-home>
|
||||
<dsh-feedback fxHide.lt-md></dsh-feedback>
|
@ -1,7 +1,32 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { Component, OnInit, ChangeDetectionStrategy } from '@angular/core';
|
||||
import { untilDestroyed, UntilDestroy } from '@ngneat/until-destroy';
|
||||
import * as Sentry from '@sentry/angular';
|
||||
import { first } from 'rxjs/operators';
|
||||
|
||||
import { KeycloakTokenInfoService } from '@dsh/app/shared';
|
||||
import { ContextService } from '@dsh/app/shared/services/context';
|
||||
|
||||
import { BootstrapService } from '../bootstrap.service';
|
||||
|
||||
@UntilDestroy()
|
||||
@Component({
|
||||
selector: 'dsh-sections',
|
||||
template: `<router-outlet></router-outlet>`,
|
||||
templateUrl: 'sections.component.html',
|
||||
providers: [ContextService, BootstrapService],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class SectionsComponent {}
|
||||
export class SectionsComponent implements OnInit {
|
||||
bootstrapped$ = this.bootstrapService.bootstrapped$;
|
||||
|
||||
constructor(
|
||||
private bootstrapService: BootstrapService,
|
||||
private keycloakTokenInfoService: KeycloakTokenInfoService
|
||||
) {}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.bootstrapService.bootstrap();
|
||||
this.keycloakTokenInfoService.partyID$
|
||||
.pipe(first(), untilDestroyed(this))
|
||||
.subscribe((partyID) => Sentry.setUser({ id: partyID }));
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,14 @@
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { NgModule } from '@angular/core';
|
||||
import { ExtendedModule } from '@angular/flex-layout';
|
||||
import { MAT_DIALOG_DEFAULT_OPTIONS } from '@angular/material/dialog';
|
||||
import { DEBOUNCE_FETCHER_ACTION_TIME, DEFAULT_FETCHER_DEBOUNCE_ACTION_TIME } from '@rbkmoney/partial-fetcher';
|
||||
|
||||
import { ShopModule } from '@dsh/api/shop';
|
||||
import { WalletModule } from '@dsh/api/wallet';
|
||||
|
||||
import { FeedbackModule } from '../feedback';
|
||||
import { HomeModule } from '../home';
|
||||
import { CHARTS_THEME } from './payment-section/analytics/charts-theme';
|
||||
import { SectionsRoutingModule } from './sections-routing.module';
|
||||
import { SectionsComponent } from './sections.component';
|
||||
@ -17,9 +21,15 @@ import {
|
||||
} from './tokens';
|
||||
|
||||
@NgModule({
|
||||
imports: [SectionsRoutingModule, ShopModule, WalletModule],
|
||||
declarations: [SectionsComponent],
|
||||
exports: [SectionsComponent],
|
||||
imports: [
|
||||
CommonModule,
|
||||
ShopModule,
|
||||
WalletModule,
|
||||
SectionsRoutingModule,
|
||||
FeedbackModule,
|
||||
HomeModule,
|
||||
ExtendedModule,
|
||||
],
|
||||
providers: [
|
||||
{ provide: SEARCH_LIMIT, useValue: DEFAULT_SEARCH_LIMIT },
|
||||
{ provide: MAT_DIALOG_DEFAULT_OPTIONS, useValue: DEFAULT_DIALOG_CONFIG.medium },
|
||||
@ -27,5 +37,7 @@ import {
|
||||
{ provide: DEBOUNCE_FETCHER_ACTION_TIME, useValue: DEFAULT_FETCHER_DEBOUNCE_ACTION_TIME },
|
||||
{ provide: CHARTS_THEME, useValue: DEFAULT_CHARTS_THEME },
|
||||
],
|
||||
declarations: [SectionsComponent],
|
||||
exports: [SectionsRoutingModule],
|
||||
})
|
||||
export class SectionsModule {}
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { IdGeneratorService } from '@rbkmoney/id-generator';
|
||||
import { Observable } from 'rxjs';
|
||||
import { mapTo, switchMap } from 'rxjs/operators';
|
||||
import { mapTo, switchMap, first, map } from 'rxjs/operators';
|
||||
|
||||
import { Claim, Modification } from '@dsh/api-codegen/claim-management';
|
||||
import { ClaimsService } from '@dsh/api/claims';
|
||||
@ -13,6 +13,7 @@ import {
|
||||
} from '@dsh/api/claims/claim-party-modification';
|
||||
import { createInternationalContractPayoutToolModification } from '@dsh/api/claims/claim-party-modification/claim-contract-modification/create-international-contract-payout-tool-modification';
|
||||
|
||||
import { ContextService } from '../../../../../services/context';
|
||||
import { InternationalShopEntityFormValue } from '../../types/international-shop-entity-form-value';
|
||||
import {
|
||||
payoutToolDetailsInternationalBankAccountToInternationalBankAccount,
|
||||
@ -21,16 +22,24 @@ import {
|
||||
|
||||
@Injectable()
|
||||
export class CreateInternationalShopEntityService {
|
||||
constructor(private claimsService: ClaimsService, private idGenerator: IdGeneratorService) {}
|
||||
constructor(
|
||||
private claimsService: ClaimsService,
|
||||
private idGenerator: IdGeneratorService,
|
||||
private contextService: ContextService
|
||||
) {}
|
||||
|
||||
createShop(creationData: InternationalShopEntityFormValue): Observable<Claim> {
|
||||
return this.claimsService
|
||||
.createClaim(this.createClaimsModifications(creationData))
|
||||
.pipe(
|
||||
switchMap((claim) =>
|
||||
this.claimsService.requestReviewClaimByID(claim.id, claim.revision).pipe(mapTo(claim))
|
||||
)
|
||||
);
|
||||
return this.contextService.organization$.pipe(
|
||||
first(),
|
||||
switchMap((org) =>
|
||||
this.claimsService
|
||||
.createClaim(org.id, this.createClaimsModifications(creationData))
|
||||
.pipe(map((claim) => [claim, org.id] as const))
|
||||
),
|
||||
switchMap(([claim, orgId]) =>
|
||||
this.claimsService.requestReviewClaimByID(orgId, claim.id, claim.revision).pipe(mapTo(claim))
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
private createClaimsModifications({
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { IdGeneratorService } from '@rbkmoney/id-generator';
|
||||
import { forkJoin, Observable, of } from 'rxjs';
|
||||
import { pluck, switchMap } from 'rxjs/operators';
|
||||
import { Observable } from 'rxjs';
|
||||
import { switchMap, first, map, mapTo } from 'rxjs/operators';
|
||||
|
||||
import { Claim, PartyModification } from '@dsh/api-codegen/claim-management';
|
||||
import { ClaimsService } from '@dsh/api/claims';
|
||||
@ -14,18 +14,28 @@ import {
|
||||
makeShopLocation,
|
||||
} from '@dsh/api/claims/claim-party-modification';
|
||||
|
||||
import { ContextService } from '../../../../../services/context';
|
||||
import { RussianShopForm } from '../../types/russian-shop-entity';
|
||||
|
||||
@Injectable()
|
||||
export class CreateRussianShopEntityService {
|
||||
constructor(private claimsService: ClaimsService, private idGenerator: IdGeneratorService) {}
|
||||
constructor(
|
||||
private claimsService: ClaimsService,
|
||||
private idGenerator: IdGeneratorService,
|
||||
private contextService: ContextService
|
||||
) {}
|
||||
|
||||
createShop(creationData: RussianShopForm): Observable<Claim> {
|
||||
return this.claimsService.createClaim(this.createShopCreationModifications(creationData)).pipe(
|
||||
switchMap((claim) => {
|
||||
return forkJoin([of(claim), this.claimsService.requestReviewClaimByID(claim.id, claim.revision)]);
|
||||
}),
|
||||
pluck(0)
|
||||
return this.contextService.organization$.pipe(
|
||||
first(),
|
||||
switchMap((org) =>
|
||||
this.claimsService
|
||||
.createClaim(org.id, this.createShopCreationModifications(creationData))
|
||||
.pipe(map((claim) => [claim, org.id] as const))
|
||||
),
|
||||
switchMap(([claim, orgId]) =>
|
||||
this.claimsService.requestReviewClaimByID(orgId, claim.id, claim.revision).pipe(mapTo(claim))
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -1,11 +0,0 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
|
||||
import { ContextService } from './context.service';
|
||||
|
||||
@NgModule({
|
||||
imports: [],
|
||||
declarations: [],
|
||||
exports: [],
|
||||
providers: [ContextService],
|
||||
})
|
||||
export class ContextModule {}
|
@ -1,44 +1,76 @@
|
||||
import { HttpErrorResponse } from '@angular/common/http';
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Observable, defer, concat, EMPTY, ReplaySubject } from 'rxjs';
|
||||
import { switchMap, pluck, tap, mapTo, catchError, shareReplay, distinctUntilChanged } from 'rxjs/operators';
|
||||
import { ActivatedRoute, Router, NavigationExtras } from '@angular/router';
|
||||
import { Observable, EMPTY, ReplaySubject, merge } from 'rxjs';
|
||||
import { switchMap, pluck, tap, catchError, startWith, distinctUntilChanged, shareReplay, first } from 'rxjs/operators';
|
||||
|
||||
import { OrganizationsService } from '@dsh/api';
|
||||
import { Organization } from '@dsh/api-codegen/organizations';
|
||||
|
||||
const ORGANIZATION_REG_EXP = /^(\/organization\/)([\w-]+)(.*)/;
|
||||
|
||||
@Injectable()
|
||||
export class ContextService {
|
||||
organization$: Observable<Organization> = concat(
|
||||
this.organizationsService.getContext().pipe(
|
||||
pluck('organizationId'),
|
||||
catchError((err) => {
|
||||
if (err instanceof HttpErrorResponse && err.status === 404)
|
||||
return this.initOrganization().pipe(switchMap(() => EMPTY));
|
||||
console.error(err);
|
||||
return EMPTY;
|
||||
})
|
||||
organization$: Observable<Organization> = this.route.params.pipe(
|
||||
startWith(this.route.snapshot.params),
|
||||
pluck('organizationId'),
|
||||
distinctUntilChanged(),
|
||||
switchMap((id) =>
|
||||
this.organizationsService.getOrg(id).pipe(
|
||||
catchError((err) => {
|
||||
console.error(err);
|
||||
return this.getContextOrganization();
|
||||
})
|
||||
)
|
||||
),
|
||||
defer(() => this.switchOrganization$).pipe(
|
||||
distinctUntilChanged(),
|
||||
switchMap((id) => this.organizationsService.switchContext(id).pipe(mapTo(id)))
|
||||
)
|
||||
).pipe(
|
||||
switchMap((id) => this.organizationsService.getOrg(id)),
|
||||
shareReplay(1)
|
||||
);
|
||||
|
||||
private switchOrganization$ = new ReplaySubject<string>(1);
|
||||
|
||||
constructor(private organizationsService: OrganizationsService) {}
|
||||
constructor(
|
||||
private organizationsService: OrganizationsService,
|
||||
private route: ActivatedRoute,
|
||||
private router: Router
|
||||
) {
|
||||
merge(this.switchOrganization$, this.organization$.pipe(pluck('id'))).subscribe(
|
||||
(id) =>
|
||||
void this.router.navigateByUrl(
|
||||
this.router.url.replace(ORGANIZATION_REG_EXP, (match, start, oldId, end) =>
|
||||
[start, id, end].join('')
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
switchOrganization(organizationId: string): void {
|
||||
this.switchOrganization$.next(organizationId);
|
||||
}
|
||||
|
||||
private initOrganization() {
|
||||
return this.organizationsService.listOrgMembership(1).pipe(
|
||||
pluck('result', 0, 'id'),
|
||||
tap((id) => this.switchOrganization(id))
|
||||
navigate(commands: (string | number)[], extras?: NavigationExtras): Observable<boolean> {
|
||||
return this.organization$.pipe(
|
||||
first(),
|
||||
switchMap(({ id }) => this.router.navigate(['organization', id, ...commands], extras))
|
||||
);
|
||||
}
|
||||
|
||||
private getInitOrganization() {
|
||||
return this.organizationsService.listOrgMembership(1).pipe(pluck('result', 0));
|
||||
}
|
||||
|
||||
private getContextOrganization() {
|
||||
return this.organizationsService.getContext().pipe(
|
||||
pluck('organizationId'),
|
||||
catchError((err) => {
|
||||
if (err instanceof HttpErrorResponse && err.status === 404)
|
||||
return this.getInitOrganization().pipe(
|
||||
pluck('id'),
|
||||
tap((id) => this.switchOrganization(id))
|
||||
);
|
||||
console.error(err);
|
||||
return EMPTY;
|
||||
}),
|
||||
switchMap((id) => this.organizationsService.getOrg(id))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1,2 +1 @@
|
||||
export * from './context.service';
|
||||
export * from './context.module';
|
||||
|
Loading…
Reference in New Issue
Block a user