mirror of
https://github.com/valitydev/dashboard.git
synced 2024-11-06 02:25:23 +00:00
TD-114: Remove unused: landing, onboarding & questionary modules (#28)
This commit is contained in:
parent
59e90fa15a
commit
30ba6a97f6
10
.gitmodules
vendored
10
.gitmodules
vendored
@ -1,10 +1,6 @@
|
||||
[submodule "schemes/claim-management/v0"]
|
||||
path = schemes/claim-management/v0
|
||||
url = https://github.com/rbkmoney/swag-claim-management.git
|
||||
branch = release/master
|
||||
[submodule "schemes/questionary/v0"]
|
||||
path = schemes/questionary/v0
|
||||
url = https://github.com/rbkmoney/swag-questionary.git
|
||||
url = https://github.com/valitydev/swag-claim-management.git
|
||||
branch = release/master
|
||||
[submodule "schemes/swag-analytics/v1"]
|
||||
path = schemes/swag-analytics/v1
|
||||
@ -37,8 +33,4 @@
|
||||
[submodule "schemes/organizations/v0"]
|
||||
path = schemes/organizations/v0
|
||||
url = https://github.com/rbkmoney/swag-organizations.git
|
||||
branch = release/master
|
||||
[submodule "schemes/sender/v0"]
|
||||
path = schemes/sender/v0
|
||||
url = https://github.com/rbkmoney/swag-sender.git
|
||||
branch = release/master
|
@ -7,6 +7,7 @@
|
||||
<excludeFolder url="file://$MODULE_DIR$/tmp" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/dist" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/.angular" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/.eslintcache" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
|
@ -3,7 +3,6 @@
|
||||
"outputDir": "openapi-codegen",
|
||||
"schemes": {
|
||||
"messages": "schemes/messages/v0/swagger.json",
|
||||
"organizations": "schemes/organizations/v0/openapi.json",
|
||||
"sender": "schemes/sender/v0/openapi.json"
|
||||
"organizations": "schemes/organizations/v0/openapi.json"
|
||||
}
|
||||
}
|
||||
|
@ -10,7 +10,7 @@
|
||||
"build": "ng build --extra-webpack-config webpack.extra.js",
|
||||
"test": "ng test",
|
||||
"coverage": "npx http-server -c-1 -o -p 9875 ./coverage",
|
||||
"lint-cmd": "eslint \"src/**/*.{ts,js,html}\" --max-warnings 1364",
|
||||
"lint-cmd": "eslint \"src/**/*.{ts,js,html}\" --max-warnings 1072",
|
||||
"lint-cache-cmd": "npm run lint-cmd -- --cache",
|
||||
"lint": "npm run lint-cache-cmd",
|
||||
"lint-fix": "npm run lint-cache-cmd -- --fix",
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit d8af566f1c0af2616cf34274e4600c16cf35dcf2
|
||||
Subproject commit 75f7169918c227dd137496966f763f5a33f9f578
|
@ -1 +0,0 @@
|
||||
Subproject commit 4e28f80ace9cdaa247a8671eccead90115e5e305
|
@ -1 +0,0 @@
|
||||
Subproject commit 0b92fe5adae9078c42da933c54e8a23d00b1430b
|
@ -7,13 +7,11 @@ import { ClaimManagementModule } from './claim-management';
|
||||
import { DarkApiModule } from './dark-api';
|
||||
import { MessagesModule } from './messages';
|
||||
import { OrganizationsModule } from './organizations';
|
||||
import { QuestionaryModule } from './questionary';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
CapiModule,
|
||||
ClaimManagementModule,
|
||||
QuestionaryModule,
|
||||
AnapiModule,
|
||||
AggrProxyModule,
|
||||
DarkApiModule,
|
||||
|
@ -1,18 +0,0 @@
|
||||
import { HttpClient, HttpHeaders } from '@angular/common/http';
|
||||
import { Inject, Injectable, Optional } from '@angular/core';
|
||||
|
||||
import { BASE_PATH, Configuration } from './swagger-codegen';
|
||||
import { DefaultService } from './swagger-codegen/api/default.service';
|
||||
|
||||
@Injectable()
|
||||
export class GetQuestionaryService extends DefaultService {
|
||||
constructor(
|
||||
protected httpClient: HttpClient,
|
||||
@Optional() @Inject(BASE_PATH) basePath: string,
|
||||
@Optional() configuration: Configuration
|
||||
) {
|
||||
super(httpClient, basePath, configuration);
|
||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||
this.defaultHeaders = new HttpHeaders({ 'Content-Type': 'application/json; charset=utf-8' });
|
||||
}
|
||||
}
|
@ -1,3 +0,0 @@
|
||||
export * from './questionary.module';
|
||||
export * from './swagger-codegen';
|
||||
export * from './get-questionary.service';
|
@ -1,11 +0,0 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
import { ConfigService } from '../../config';
|
||||
import { Configuration } from './swagger-codegen';
|
||||
|
||||
@Injectable()
|
||||
export class QuestionaryConfigService extends Configuration {
|
||||
constructor({ apiEndpoint }: ConfigService) {
|
||||
super({ apiKeys: {}, basePath: `${apiEndpoint}/dark-api/v1` });
|
||||
}
|
||||
}
|
@ -1,16 +0,0 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
|
||||
import { GetQuestionaryService } from './get-questionary.service';
|
||||
import { QuestionaryConfigService } from './questionary-config.service';
|
||||
import { ApiModule, Configuration } from './swagger-codegen';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
{
|
||||
ngModule: ApiModule,
|
||||
providers: [{ provide: Configuration, useClass: QuestionaryConfigService }],
|
||||
},
|
||||
],
|
||||
providers: [QuestionaryConfigService, GetQuestionaryService],
|
||||
})
|
||||
export class QuestionaryModule {}
|
@ -1,2 +0,0 @@
|
||||
export * from './sender.module';
|
||||
export * from './openapi-codegen';
|
@ -1,13 +0,0 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
import { ConfigService } from '../../config';
|
||||
import { Configuration } from './openapi-codegen';
|
||||
|
||||
const DARK_API_PATH = 'dark-api/v1';
|
||||
|
||||
@Injectable()
|
||||
export class SenderConfigService extends Configuration {
|
||||
constructor({ apiEndpoint }: ConfigService) {
|
||||
super({ apiKeys: {}, basePath: `${apiEndpoint}/${DARK_API_PATH}` });
|
||||
}
|
||||
}
|
@ -1,15 +0,0 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
|
||||
import { ApiModule, Configuration } from './openapi-codegen';
|
||||
import { SenderConfigService } from './sender-config.service';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
{
|
||||
ngModule: ApiModule,
|
||||
providers: [{ provide: Configuration, useClass: SenderConfigService }],
|
||||
},
|
||||
],
|
||||
providers: [SenderConfigService],
|
||||
})
|
||||
export class SenderModule {}
|
@ -1,6 +1,7 @@
|
||||
import { HttpErrorResponse } from '@angular/common/http';
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Observable } from 'rxjs';
|
||||
import { first, switchMap } from 'rxjs/operators';
|
||||
import { Observable, throwError } from 'rxjs';
|
||||
import { first, switchMap, catchError } from 'rxjs/operators';
|
||||
|
||||
import {
|
||||
Claim,
|
||||
@ -28,13 +29,19 @@ export class ClaimsService {
|
||||
claimID?: number,
|
||||
continuationToken?: string
|
||||
) {
|
||||
return this.claimsService.searchClaims(
|
||||
this.idGenerator.shortUuid(),
|
||||
limit,
|
||||
undefined,
|
||||
continuationToken,
|
||||
claimID,
|
||||
claimStatuses || Object.values(StatusModificationUnit.StatusEnum)
|
||||
return this.keycloakTokenInfoService.partyID$.pipe(
|
||||
first(),
|
||||
switchMap((partyID) =>
|
||||
this.claimsService.searchClaims(
|
||||
this.idGenerator.shortUuid(),
|
||||
partyID,
|
||||
limit,
|
||||
undefined,
|
||||
continuationToken,
|
||||
claimID,
|
||||
claimStatuses || Object.values(StatusModificationUnit.StatusEnum)
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@ -43,7 +50,10 @@ export class ClaimsService {
|
||||
}
|
||||
|
||||
getClaimByID(claimID: number): Observable<Claim> {
|
||||
return this.claimsService.getClaimByID(this.idGenerator.shortUuid(), claimID);
|
||||
return this.keycloakTokenInfoService.partyID$.pipe(
|
||||
first(),
|
||||
switchMap((partyID) => this.claimsService.getClaimByID(this.idGenerator.shortUuid(), partyID, claimID))
|
||||
);
|
||||
}
|
||||
|
||||
createClaim(changeset: Modification[]): Observable<Claim> {
|
||||
@ -88,7 +98,24 @@ export class ClaimsService {
|
||||
return this.keycloakTokenInfoService.partyID$.pipe(
|
||||
first(),
|
||||
switchMap((partyId) =>
|
||||
this.claimsService.requestReviewClaimByID(this.idGenerator.shortUuid(), partyId, claimID, claimRevision)
|
||||
this.claimsService
|
||||
.requestReviewClaimByID(this.idGenerator.shortUuid(), partyId, claimID, claimRevision)
|
||||
.pipe(
|
||||
catchError((err) => {
|
||||
if (err instanceof HttpErrorResponse && err.error?.code === 'invalidClaimRevision')
|
||||
return this.getClaimByID(claimID).pipe(
|
||||
switchMap((claim) =>
|
||||
this.claimsService.requestReviewClaimByID(
|
||||
this.idGenerator.shortUuid(),
|
||||
partyId,
|
||||
claim.id,
|
||||
claim.revision
|
||||
)
|
||||
)
|
||||
);
|
||||
return throwError(err);
|
||||
})
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
@ -3,7 +3,6 @@ export * from './claims';
|
||||
export * from './shop';
|
||||
export * from './invoice';
|
||||
export * from './search';
|
||||
export * from './questionary';
|
||||
export * from './reports';
|
||||
export * from './dadata';
|
||||
export * from './files';
|
||||
|
@ -1,2 +1,3 @@
|
||||
export * from './kontur-focus.module';
|
||||
export * from './kontur-focus.service';
|
||||
export * from './utils';
|
||||
|
@ -0,0 +1,3 @@
|
||||
export function createIndividualEntityRegisteredName(fio: string): string {
|
||||
return `ИП ${fio}`;
|
||||
}
|
4
src/app/api/kontur-focus/utils/index.ts
Normal file
4
src/app/api/kontur-focus/utils/index.ts
Normal file
@ -0,0 +1,4 @@
|
||||
export * from './is-req-individual-entity';
|
||||
export * from './is-req-legal-entity';
|
||||
export * from './get-address';
|
||||
export * from './create-individual-entity-registered-name';
|
@ -0,0 +1,5 @@
|
||||
import { ReqContractor, ReqIndividualEntity } from '@dsh/api-codegen/aggr-proxy';
|
||||
|
||||
export function isReqIndividualEntity(contractor: ReqContractor): contractor is ReqIndividualEntity {
|
||||
return contractor.reqContractorType === 'ReqIndividualEntity';
|
||||
}
|
5
src/app/api/kontur-focus/utils/is-req-legal-entity.ts
Normal file
5
src/app/api/kontur-focus/utils/is-req-legal-entity.ts
Normal file
@ -0,0 +1,5 @@
|
||||
import { ReqContractor, ReqLegalEntity } from '@dsh/api-codegen/aggr-proxy';
|
||||
|
||||
export function isReqLegalEntity(contractor: ReqContractor): contractor is ReqLegalEntity {
|
||||
return contractor.reqContractorType === 'ReqLegalEntity';
|
||||
}
|
@ -1,4 +0,0 @@
|
||||
export * from './questionary.module';
|
||||
export * from './questionary.service';
|
||||
export * from './type-guards';
|
||||
export * from './model';
|
@ -1,5 +0,0 @@
|
||||
export enum AuthorityConfirmingDocumentType {
|
||||
SolePartyDecision = 'solePartyDecision',
|
||||
MeetingOfShareholders = 'meetingOfShareholders',
|
||||
MeetingOfParticipants = 'meetingOfParticipants',
|
||||
}
|
@ -1 +0,0 @@
|
||||
export * from './authority-confirming-document-type';
|
@ -1,8 +0,0 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
|
||||
import { QuestionaryService } from './questionary.service';
|
||||
|
||||
@NgModule({
|
||||
providers: [QuestionaryService],
|
||||
})
|
||||
export class QuestionaryModule {}
|
@ -1,40 +0,0 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { from, Observable } from 'rxjs';
|
||||
import { pluck, switchMap } from 'rxjs/operators';
|
||||
|
||||
import {
|
||||
GetQuestionaryService,
|
||||
QuestionaryData,
|
||||
QuestionaryService as SaveQuestionaryService,
|
||||
Snapshot,
|
||||
Version,
|
||||
} from '@dsh/api-codegen/questionary';
|
||||
|
||||
import { KeycloakService } from '../../auth';
|
||||
|
||||
@Injectable()
|
||||
export class QuestionaryService {
|
||||
constructor(
|
||||
private saveQuestionaryService: SaveQuestionaryService,
|
||||
private getQuestionaryService: GetQuestionaryService,
|
||||
private keycloakService: KeycloakService
|
||||
) {}
|
||||
|
||||
getQuestionary(questionaryId: string, version?: string): Observable<Snapshot> {
|
||||
return this.getQuestionaryService.getQuestionary(questionaryId, version);
|
||||
}
|
||||
|
||||
saveQuestionary(id: string, data: QuestionaryData, version?: Version): Observable<Version> {
|
||||
return from(this.keycloakService.loadUserProfile()).pipe(
|
||||
pluck('email'),
|
||||
switchMap((ownerId) =>
|
||||
this.saveQuestionaryService.saveQuestionary({
|
||||
id,
|
||||
ownerId,
|
||||
data,
|
||||
version,
|
||||
})
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
@ -1,3 +0,0 @@
|
||||
export * from './russian-individual-entity-questionary';
|
||||
export * from './russian-legal-entity-questionary';
|
||||
export * from './international-legal-entity-questionary';
|
@ -1,21 +0,0 @@
|
||||
import { Overwrite } from 'utility-types';
|
||||
|
||||
import {
|
||||
Contractor,
|
||||
InternationalLegalEntity,
|
||||
LegalEntity,
|
||||
LegalEntityContractor,
|
||||
} from '@dsh/api-codegen/questionary/swagger-codegen';
|
||||
|
||||
type InternationalLegalEntityContractor = Overwrite<
|
||||
LegalEntityContractor,
|
||||
{
|
||||
legalEntity: Overwrite<LegalEntity, InternationalLegalEntity>;
|
||||
}
|
||||
>;
|
||||
|
||||
export const isInternationalLegalEntityContractor = (
|
||||
contractor: LegalEntityContractor
|
||||
): contractor is InternationalLegalEntityContractor =>
|
||||
contractor.contractorType === Contractor.ContractorTypeEnum.LegalEntityContractor &&
|
||||
contractor.legalEntity.legalEntityType === LegalEntity.LegalEntityTypeEnum.InternationalLegalEntity;
|
@ -1,47 +0,0 @@
|
||||
import { Overwrite } from 'utility-types';
|
||||
|
||||
import {
|
||||
Contractor,
|
||||
IndividualEntity,
|
||||
IndividualEntityContractor,
|
||||
IndividualRegistrationInfo,
|
||||
IndividualResidencyInfo,
|
||||
Questionary,
|
||||
QuestionaryData,
|
||||
RussianIndividualEntity,
|
||||
} from '@dsh/api-codegen/questionary';
|
||||
|
||||
type RussianIndividualEntityContractor = Overwrite<
|
||||
IndividualEntityContractor,
|
||||
{
|
||||
individualEntity: Overwrite<
|
||||
RussianIndividualEntity,
|
||||
{
|
||||
residencyInfo: IndividualResidencyInfo;
|
||||
registrationInfo: IndividualRegistrationInfo;
|
||||
}
|
||||
>;
|
||||
}
|
||||
>;
|
||||
type RussianIndividualEntityQuestionaryData = Overwrite<
|
||||
QuestionaryData,
|
||||
{ contractor: RussianIndividualEntityContractor }
|
||||
>;
|
||||
|
||||
export type RussianIndividualEntityQuestionary = Overwrite<
|
||||
Questionary,
|
||||
{ data: RussianIndividualEntityQuestionaryData }
|
||||
>;
|
||||
|
||||
export const isRussianIndividualEntityContractor = (
|
||||
contractor: IndividualEntityContractor
|
||||
): contractor is RussianIndividualEntityContractor =>
|
||||
contractor.contractorType === Contractor.ContractorTypeEnum.IndividualEntityContractor &&
|
||||
contractor.individualEntity.individualEntityType ===
|
||||
IndividualEntity.IndividualEntityTypeEnum.RussianIndividualEntity;
|
||||
|
||||
export function isRussianIndividualEntityQuestionary(
|
||||
questionary: Questionary
|
||||
): questionary is RussianIndividualEntityQuestionary {
|
||||
return questionary?.data?.contractor && isRussianIndividualEntityContractor(questionary.data.contractor);
|
||||
}
|
@ -1,49 +0,0 @@
|
||||
import { Overwrite } from 'utility-types';
|
||||
|
||||
import {
|
||||
Contractor,
|
||||
LegalEntity,
|
||||
LegalEntityContractor,
|
||||
LegalRegistrationInfo,
|
||||
LegalResidencyInfo,
|
||||
Questionary,
|
||||
QuestionaryData,
|
||||
RussianLegalEntity,
|
||||
} from '@dsh/api-codegen/questionary';
|
||||
|
||||
type RussianLegalEntityContractor = Overwrite<
|
||||
LegalEntityContractor,
|
||||
{
|
||||
legalEntity: Overwrite<
|
||||
RussianLegalEntity,
|
||||
{
|
||||
residencyInfo: LegalResidencyInfo;
|
||||
registrationInfo: LegalRegistrationInfo;
|
||||
}
|
||||
>;
|
||||
}
|
||||
>;
|
||||
type RussianLegalEntityQuestionaryData = Overwrite<
|
||||
QuestionaryData,
|
||||
{
|
||||
contractor: RussianLegalEntityContractor;
|
||||
}
|
||||
>;
|
||||
export type RussianLegalEntityQuestionary = Overwrite<
|
||||
Questionary,
|
||||
{
|
||||
data: RussianLegalEntityQuestionaryData;
|
||||
}
|
||||
>;
|
||||
|
||||
export const isRussianLegalEntityContractor = (
|
||||
contractor: LegalEntityContractor
|
||||
): contractor is RussianLegalEntityContractor =>
|
||||
contractor.contractorType === Contractor.ContractorTypeEnum.LegalEntityContractor &&
|
||||
contractor.legalEntity.legalEntityType === LegalEntity.LegalEntityTypeEnum.RussianLegalEntity;
|
||||
|
||||
export function isRussianLegalEntityQuestionary(
|
||||
questionary: Questionary
|
||||
): questionary is RussianLegalEntityQuestionary {
|
||||
return questionary?.data?.contractor && isRussianLegalEntityContractor(questionary.data.contractor);
|
||||
}
|
@ -1,2 +0,0 @@
|
||||
export * from './sender.module';
|
||||
export * from './services/messages/messages.service';
|
@ -1,10 +0,0 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
|
||||
import { SenderModule as ApiSenderModule } from '../../api-codegen/sender';
|
||||
import { MessagesService } from './services/messages/messages.service';
|
||||
|
||||
@NgModule({
|
||||
imports: [ApiSenderModule],
|
||||
providers: [MessagesService],
|
||||
})
|
||||
export class SenderModule {}
|
@ -1,15 +0,0 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
import { IdGeneratorService } from '@dsh/app/shared';
|
||||
|
||||
import { MessagesService as ApiMessagesService } from '../../../../api-codegen/sender';
|
||||
|
||||
@Injectable()
|
||||
export class MessagesService {
|
||||
constructor(private messagesService: ApiMessagesService, private idGeneratorService: IdGeneratorService) {}
|
||||
|
||||
sendFeedbackEmailMsg(text: string): Observable<any> {
|
||||
return this.messagesService.sendFeedbackEmailMsg(this.idGeneratorService.shortUuid(), { text });
|
||||
}
|
||||
}
|
@ -7,13 +7,10 @@ interface AppConfig {
|
||||
urlShortenerEndpoint: string;
|
||||
checkoutEndpoint: string;
|
||||
docsEndpoints: {
|
||||
help: string;
|
||||
developer: string;
|
||||
rbk: string;
|
||||
payments: string;
|
||||
};
|
||||
theme: {
|
||||
name: string;
|
||||
isMainBackgroundImages: boolean;
|
||||
};
|
||||
sentryDsn?: string;
|
||||
keycloakEndpoint: string;
|
||||
|
@ -1,15 +0,0 @@
|
||||
@use '@angular/material' as mat;
|
||||
|
||||
@mixin dsh-feedback-theme($theme) {
|
||||
$primary: map-get($theme, primary);
|
||||
$foreground: map-get($theme, foreground);
|
||||
$contrast-text: map-get($foreground, contrast-text);
|
||||
|
||||
.dsh-feedback {
|
||||
&,
|
||||
&:hover {
|
||||
background: mat.get-color-from-palette($primary, default);
|
||||
color: $contrast-text;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
<div
|
||||
class="dsh-feedback dsh-button"
|
||||
*transloco="let t; scope: 'feedback'; read: 'feedback'"
|
||||
(click)="openFeedbackDialog()"
|
||||
>
|
||||
{{ t('label') }}
|
||||
</div>
|
@ -1,16 +0,0 @@
|
||||
$HEIGHT: 24px;
|
||||
$PADDING_TEXT: 16px;
|
||||
$PADDING_BOTTOM: 80px;
|
||||
$BORDER_RADIUS: 29px;
|
||||
|
||||
.dsh-feedback {
|
||||
position: fixed;
|
||||
right: 0;
|
||||
bottom: $PADDING_BOTTOM;
|
||||
height: $HEIGHT;
|
||||
line-height: $HEIGHT;
|
||||
border-radius: $BORDER_RADIUS $BORDER_RADIUS 0 0;
|
||||
padding: 0 $PADDING_TEXT;
|
||||
transform-origin: 100% 100%;
|
||||
transform: rotate(-90deg) translate(100%, 0);
|
||||
}
|
@ -1,38 +0,0 @@
|
||||
import { Component, DebugElement } from '@angular/core';
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { MatDialogModule } from '@angular/material/dialog';
|
||||
import { By } from '@angular/platform-browser';
|
||||
|
||||
import { DIALOG_CONFIG } from '@dsh/app/sections/tokens';
|
||||
|
||||
import { FeedbackComponent } from './feedback.component';
|
||||
|
||||
@Component({
|
||||
selector: 'dsh-host',
|
||||
template: `<dsh-feedback></dsh-feedback>`,
|
||||
})
|
||||
class HostComponent {}
|
||||
|
||||
describe('FeedbackComponent', () => {
|
||||
let fixture: ComponentFixture<HostComponent>;
|
||||
let debugElement: DebugElement;
|
||||
let component: FeedbackComponent;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
imports: [MatDialogModule],
|
||||
declarations: [HostComponent, FeedbackComponent],
|
||||
providers: [{ provide: DIALOG_CONFIG, useValue: {} }],
|
||||
}).compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(HostComponent);
|
||||
debugElement = fixture.debugElement.query(By.directive(FeedbackComponent));
|
||||
component = debugElement.componentInstance;
|
||||
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should be created', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
@ -1,18 +0,0 @@
|
||||
import { ChangeDetectionStrategy, Component } from '@angular/core';
|
||||
import { MatDialog, MatDialogRef } from '@angular/material/dialog';
|
||||
|
||||
import { FeedbackDialogComponent } from '@dsh/app/shared/components/dialog';
|
||||
|
||||
@Component({
|
||||
selector: 'dsh-feedback',
|
||||
templateUrl: 'feedback.component.html',
|
||||
styleUrls: ['feedback.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class FeedbackComponent {
|
||||
constructor(private dialog: MatDialog) {}
|
||||
|
||||
openFeedbackDialog(): MatDialogRef<FeedbackDialogComponent> {
|
||||
return this.dialog.open(FeedbackDialogComponent);
|
||||
}
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { NgModule } from '@angular/core';
|
||||
import { TranslocoModule } from '@ngneat/transloco';
|
||||
|
||||
import { FeedbackDialogModule } from '@dsh/app/shared/components/dialog';
|
||||
|
||||
import { FeedbackComponent } from './feedback.component';
|
||||
|
||||
@NgModule({
|
||||
imports: [CommonModule, TranslocoModule, FeedbackDialogModule],
|
||||
declarations: [FeedbackComponent],
|
||||
exports: [FeedbackComponent],
|
||||
})
|
||||
export class FeedbackModule {}
|
@ -1,2 +0,0 @@
|
||||
export * from './feedback.component';
|
||||
export * from './feedback.module';
|
@ -5,10 +5,14 @@ $height: 48px;
|
||||
}
|
||||
|
||||
mat-icon {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
cursor: pointer;
|
||||
outline: none;
|
||||
|
||||
&,
|
||||
::ng-deep svg {
|
||||
height: 100%;
|
||||
width: auto;
|
||||
}
|
||||
}
|
||||
|
||||
.brand-wrapper {
|
||||
|
@ -1,7 +1,5 @@
|
||||
import { ChangeDetectionStrategy, Component, Input } from '@angular/core';
|
||||
|
||||
import { coerceBoolean } from '@dsh/utils';
|
||||
|
||||
@Component({
|
||||
selector: 'dsh-brand',
|
||||
templateUrl: 'brand.component.html',
|
||||
@ -9,6 +7,5 @@ import { coerceBoolean } from '@dsh/utils';
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class BrandComponent {
|
||||
@Input() @coerceBoolean inverted = false;
|
||||
@Input() navigationLink = '/';
|
||||
}
|
||||
|
@ -1,5 +1,4 @@
|
||||
<div *ngIf="routerNavigationEnd$ | async">
|
||||
<dsh-welcome-image *ngIf="hasBackground"></dsh-welcome-image>
|
||||
<ng-container *ngTemplateOutlet="(isXSmallSmall$ | async) ? mobile : laptop"> </ng-container>
|
||||
</div>
|
||||
|
||||
@ -8,13 +7,13 @@
|
||||
</ng-template>
|
||||
|
||||
<ng-template #mobile>
|
||||
<dsh-mobile-grid [inverted]="hasBackground">
|
||||
<dsh-mobile-grid>
|
||||
<ng-container *ngTemplateOutlet="content"></ng-container>
|
||||
</dsh-mobile-grid>
|
||||
</ng-template>
|
||||
|
||||
<ng-template #laptop>
|
||||
<dsh-laptop-grid [inverted]="hasBackground">
|
||||
<dsh-laptop-grid>
|
||||
<ng-container *ngTemplateOutlet="content"></ng-container>
|
||||
</dsh-laptop-grid>
|
||||
</ng-template>
|
||||
|
@ -23,10 +23,6 @@ export class HomeComponent implements OnInit {
|
||||
private breakpointObserver: BreakpointObserver
|
||||
) {}
|
||||
|
||||
get hasBackground(): boolean {
|
||||
return this.router.url === '/' && this.themeManager.isMainBackgroundImages;
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.routerNavigationEnd$ = this.router.events.pipe(
|
||||
filter((event: RouterEvent) => event instanceof NavigationEnd),
|
||||
|
@ -9,7 +9,6 @@ import { HomeComponent } from './home.component';
|
||||
import { LaptopGridModule } from './laptop-grid/laptop-grid.module';
|
||||
import { MobileGridModule } from './mobile-grid/mobile-grid.module';
|
||||
import { ToolbarModule } from './toolbar';
|
||||
import { WelcomeImageModule } from './welcome-image';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
@ -18,7 +17,6 @@ import { WelcomeImageModule } from './welcome-image';
|
||||
RouterModule,
|
||||
FlexLayoutModule,
|
||||
MatIconModule,
|
||||
WelcomeImageModule,
|
||||
MobileGridModule,
|
||||
LaptopGridModule,
|
||||
ConfigModule,
|
||||
|
@ -1,4 +1,4 @@
|
||||
<div class="dsh-laptop-grid" fxLayout="column" fxLayoutGap="48px">
|
||||
<dsh-toolbar [inverted]="inverted"></dsh-toolbar>
|
||||
<dsh-toolbar></dsh-toolbar>
|
||||
<ng-content></ng-content>
|
||||
</div>
|
||||
|
@ -1,14 +1,8 @@
|
||||
import { Component, Input } from '@angular/core';
|
||||
|
||||
import { coerceBoolean } from '@dsh/utils';
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'dsh-laptop-grid',
|
||||
templateUrl: './laptop-grid.component.html',
|
||||
styleUrls: ['./laptop-grid.component.scss'],
|
||||
})
|
||||
export class LaptopGridComponent {
|
||||
@Input()
|
||||
@coerceBoolean
|
||||
inverted: boolean;
|
||||
}
|
||||
export class LaptopGridComponent {}
|
||||
|
@ -11,7 +11,7 @@
|
||||
<div class="dsh-mobile-grid-content" fxLayout="column" fxLayoutGap="24px">
|
||||
<div class="dsh-mobile-grid-content-actions" fxLayout="row" fxLayoutAlign="start center" fxLayoutGap="24px">
|
||||
<dsh-bi class="dsh-mobile-grid-toggle-button" (click)="openSideNav()" icon="list" size="lg"></dsh-bi>
|
||||
<dsh-brand [inverted]="inverted"></dsh-brand>
|
||||
<dsh-brand></dsh-brand>
|
||||
</div>
|
||||
<ng-content></ng-content>
|
||||
</div>
|
||||
|
@ -1,18 +1,12 @@
|
||||
import { Component, Input, ViewChild } from '@angular/core';
|
||||
import { Component, ViewChild } from '@angular/core';
|
||||
import { MatDrawer, MatDrawerToggleResult } from '@angular/material/sidenav';
|
||||
|
||||
import { coerceBoolean } from '@dsh/utils';
|
||||
|
||||
@Component({
|
||||
selector: 'dsh-mobile-grid',
|
||||
templateUrl: './mobile-grid.component.html',
|
||||
styleUrls: ['./mobile-grid.component.scss'],
|
||||
})
|
||||
export class MobileGridComponent {
|
||||
@Input()
|
||||
@coerceBoolean
|
||||
inverted: boolean;
|
||||
|
||||
@ViewChild(MatDrawer) drawer: MatDrawer;
|
||||
|
||||
openSideNav(): Promise<MatDrawerToggleResult> {
|
||||
|
@ -1,3 +1,2 @@
|
||||
export * from './mobile-menu-nav-item';
|
||||
export * from './mobile-menu-feedback-item';
|
||||
export * from './mobile-user-bar';
|
||||
|
@ -1 +0,0 @@
|
||||
export * from './mobile-menu-feedback-item.component';
|
@ -1,3 +0,0 @@
|
||||
<dsh-mobile-menu-nav-item *transloco="let t; scope: 'toolbar'; read: 'toolbar.nav'" (click)="openFeedbackDialog()">{{
|
||||
t('feedback')
|
||||
}}</dsh-mobile-menu-nav-item>
|
@ -1,17 +0,0 @@
|
||||
import { ChangeDetectionStrategy, Component } from '@angular/core';
|
||||
import { MatDialog, MatDialogRef } from '@angular/material/dialog';
|
||||
|
||||
import { FeedbackDialogComponent } from '@dsh/app/shared/components/dialog';
|
||||
|
||||
@Component({
|
||||
selector: 'dsh-mobile-menu-feedback-item',
|
||||
templateUrl: 'mobile-menu-feedback-item.component.html',
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class MobileMenuFeedbackItemComponent {
|
||||
constructor(private dialog: MatDialog) {}
|
||||
|
||||
openFeedbackDialog(): MatDialogRef<FeedbackDialogComponent> {
|
||||
return this.dialog.open(FeedbackDialogComponent);
|
||||
}
|
||||
}
|
@ -10,7 +10,6 @@
|
||||
(click)="menuItemSelected.emit()"
|
||||
>{{ link.label }}</dsh-mobile-menu-nav-item
|
||||
>
|
||||
<dsh-mobile-menu-feedback-item></dsh-mobile-menu-feedback-item>
|
||||
</div>
|
||||
<mat-divider></mat-divider>
|
||||
<dsh-mobile-user-bar></dsh-mobile-user-bar>
|
||||
|
@ -8,7 +8,7 @@ import { TranslocoModule } from '@ngneat/transloco';
|
||||
import { SectionsLinksModule } from '@dsh/app/shared/services/sections-links';
|
||||
import { BootstrapIconModule } from '@dsh/components/indicators';
|
||||
|
||||
import { MobileMenuFeedbackItemComponent, MobileUserBarComponent, NavItemComponent } from './components';
|
||||
import { MobileUserBarComponent, NavItemComponent } from './components';
|
||||
import { MobileMenuComponent } from './mobile-menu.component';
|
||||
|
||||
@NgModule({
|
||||
@ -21,7 +21,7 @@ import { MobileMenuComponent } from './mobile-menu.component';
|
||||
TranslocoModule,
|
||||
BootstrapIconModule,
|
||||
],
|
||||
declarations: [MobileMenuComponent, NavItemComponent, MobileMenuFeedbackItemComponent, MobileUserBarComponent],
|
||||
declarations: [MobileMenuComponent, NavItemComponent, MobileUserBarComponent],
|
||||
exports: [MobileMenuComponent],
|
||||
})
|
||||
export class MobileMenuModule {}
|
||||
|
@ -1,7 +1,7 @@
|
||||
<div class="dsh-toolbar" fxLayout fxLayoutGap="24px">
|
||||
<dsh-brand fxFlex fxLayoutAlign="start" [inverted]="inverted"></dsh-brand>
|
||||
<dsh-brand fxFlex fxLayoutAlign="start"></dsh-brand>
|
||||
<div fxFlex fxLayoutAlign="center">
|
||||
<nav class="dsh-top-tab-nav-bar" [class.dsh-inverted-nav-bar]="inverted" mat-tab-nav-bar>
|
||||
<nav class="dsh-top-tab-nav-bar" mat-tab-nav-bar>
|
||||
<a
|
||||
*ngFor="let link of sectionLinks$ | async"
|
||||
mat-tab-link
|
||||
|
@ -1,7 +1,6 @@
|
||||
import { ChangeDetectionStrategy, Component, Input } from '@angular/core';
|
||||
import { ChangeDetectionStrategy, Component } from '@angular/core';
|
||||
|
||||
import { SectionsLinksService } from '@dsh/app/shared/services/sections-links';
|
||||
import { coerceBoolean } from '@dsh/utils';
|
||||
|
||||
@Component({
|
||||
selector: 'dsh-toolbar',
|
||||
@ -10,8 +9,6 @@ import { coerceBoolean } from '@dsh/utils';
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class ToolbarComponent {
|
||||
@Input() @coerceBoolean inverted: boolean;
|
||||
|
||||
sectionLinks$ = this.sectionsLinksService.sectionLinks$;
|
||||
|
||||
constructor(private sectionsLinksService: SectionsLinksService) {}
|
||||
|
@ -1,10 +0,0 @@
|
||||
@use '@angular/material' as mat;
|
||||
@import 'node_modules/@angular/material/theming';
|
||||
|
||||
@mixin dsh-welcome-image-theme($theme) {
|
||||
$primary: map-get($theme, primary);
|
||||
|
||||
.dsh-welcome-image {
|
||||
background-color: mat.get-color-from-palette($primary, default);
|
||||
}
|
||||
}
|
@ -1,2 +0,0 @@
|
||||
export * from './welcome-image.module';
|
||||
export * from './welcome-image.component';
|
@ -1 +0,0 @@
|
||||
<div class="dsh-welcome-image" [style.background-image]="'url(' + imageUrl + ')'"></div>
|
@ -1,8 +0,0 @@
|
||||
$dsh-welcome-image-height: 650px;
|
||||
|
||||
.dsh-welcome-image {
|
||||
height: $dsh-welcome-image-height;
|
||||
margin-bottom: -$dsh-welcome-image-height;
|
||||
background-position: center;
|
||||
background-size: cover;
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
import { ChangeDetectionStrategy, Component } from '@angular/core';
|
||||
import random from 'lodash-es/random';
|
||||
|
||||
@Component({
|
||||
selector: 'dsh-welcome-image',
|
||||
templateUrl: 'welcome-image.component.html',
|
||||
styleUrls: ['welcome-image.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class WelcomeImageComponent {
|
||||
imageUrls = [
|
||||
'assets/background/1.png',
|
||||
'assets/background/2.png',
|
||||
'assets/background/3.png',
|
||||
'assets/background/4.png',
|
||||
'assets/background/5.png',
|
||||
];
|
||||
|
||||
get imageUrl() {
|
||||
const idx = random(0, this.imageUrls.length - 1);
|
||||
return this.imageUrls[idx];
|
||||
}
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { NgModule } from '@angular/core';
|
||||
|
||||
import { WelcomeImageComponent } from './welcome-image.component';
|
||||
|
||||
@NgModule({
|
||||
imports: [CommonModule],
|
||||
exports: [WelcomeImageComponent],
|
||||
declarations: [WelcomeImageComponent],
|
||||
})
|
||||
export class WelcomeImageModule {}
|
@ -1,17 +1 @@
|
||||
[
|
||||
"apple_pay",
|
||||
"bill",
|
||||
"bill_persian_green",
|
||||
"bill_solitude",
|
||||
"google_pay",
|
||||
"logo",
|
||||
"mastercard",
|
||||
"mir",
|
||||
"reading_patrick",
|
||||
"samsung_pay",
|
||||
"visa",
|
||||
"wallet",
|
||||
"wallet_persian_green",
|
||||
"wallet_solitude",
|
||||
"yandex_pay"
|
||||
]
|
||||
["apple_pay", "google_pay", "logo", "mastercard", "mir", "samsung_pay", "visa", "yandex_pay"]
|
||||
|
@ -1,68 +0,0 @@
|
||||
<div
|
||||
*transloco="
|
||||
let t;
|
||||
scope: 'claim-modification-containers';
|
||||
read: 'claimModificationContainers.documentContainer.additionalInfo'
|
||||
"
|
||||
fxLayout="column"
|
||||
fxLayoutGap="10px"
|
||||
>
|
||||
<mat-divider></mat-divider>
|
||||
<dsh-details-item *ngIf="additionalInfo?.staffCount" [title]="t('staffCount')">
|
||||
{{ additionalInfo?.staffCount }}
|
||||
</dsh-details-item>
|
||||
<div fxLayout="row" *ngIf="accountantInfo?.accountantInfoType !== 'WithChiefAccountant'">
|
||||
<dsh-details-item fxFlex="50" *ngIf="accountantInfo?.accountantInfoType" [title]="t('accountantTypeLabel')">
|
||||
<span
|
||||
*transloco="
|
||||
let accountantTypes;
|
||||
scope: 'claim-modification-containers';
|
||||
read: 'claimModificationContainers.documentContainer.additionalInfo.accountantTypes'
|
||||
"
|
||||
>{{ accountantTypes(accountantInfo?.accountantInfoType) }}</span
|
||||
>
|
||||
</dsh-details-item>
|
||||
<dsh-details-item fxFlex="50" *ngIf="accountantInfo?.inn" [title]="t('accountantOrgInn')">
|
||||
{{ accountantInfo?.inn }}
|
||||
</dsh-details-item>
|
||||
</div>
|
||||
<div fxLayout="row">
|
||||
<dsh-details-item fxFlex="50" *ngIf="additionalInfo?.hasBeneficiary" [title]="t('hasBeneficiary')">
|
||||
{{ t('trueFlag') }}
|
||||
</dsh-details-item>
|
||||
<dsh-details-item
|
||||
fxFlex="50"
|
||||
*ngIf="additionalInfo?.hasLiquidationProcess"
|
||||
[title]="t('hasLiquidationProcess')"
|
||||
>
|
||||
{{ t('trueFlag') }}
|
||||
</dsh-details-item>
|
||||
</div>
|
||||
<mat-divider></mat-divider>
|
||||
<div fxLayout="row">
|
||||
<dsh-details-item
|
||||
fxFlex="50"
|
||||
*ngIf="additionalInfo?.monthOperationCount"
|
||||
[title]="t('monthOperationCountLabel')"
|
||||
>
|
||||
<span
|
||||
*transloco="
|
||||
let monthOperationCountTypes;
|
||||
scope: 'claim-modification-containers';
|
||||
read: 'claimModificationContainers.documentContainer.additionalInfo.monthOperationCountTypes'
|
||||
"
|
||||
>{{ monthOperationCountTypes(additionalInfo.monthOperationCount) }}</span
|
||||
>
|
||||
</dsh-details-item>
|
||||
<dsh-details-item fxFlex="50" *ngIf="additionalInfo?.monthOperationSum" [title]="t('monthOperationSumLabel')">
|
||||
<span
|
||||
*transloco="
|
||||
let monthOperationSumTypes;
|
||||
scope: 'claim-modification-containers';
|
||||
read: 'claimModificationContainers.documentContainer.additionalInfo.monthOperationSumTypes'
|
||||
"
|
||||
>{{ monthOperationSumTypes(additionalInfo.monthOperationSum) }}</span
|
||||
>
|
||||
</dsh-details-item>
|
||||
</div>
|
||||
</div>
|
@ -1,19 +0,0 @@
|
||||
import { ChangeDetectionStrategy, Component, Input, OnChanges, SimpleChanges } from '@angular/core';
|
||||
import get from 'lodash-es/get';
|
||||
|
||||
import { AdditionalInfo, WithoutChiefAccountingOrganization } from '@dsh/api-codegen/questionary';
|
||||
|
||||
@Component({
|
||||
selector: 'dsh-additional-info',
|
||||
templateUrl: 'additional-info.component.html',
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class AdditionalInfoComponent implements OnChanges {
|
||||
@Input() additionalInfo: AdditionalInfo;
|
||||
|
||||
accountantInfo: WithoutChiefAccountingOrganization;
|
||||
|
||||
ngOnChanges({ additionalInfo }: SimpleChanges) {
|
||||
this.accountantInfo = get(additionalInfo, ['currentValue', 'accountantInfo']);
|
||||
}
|
||||
}
|
@ -1 +0,0 @@
|
||||
export * from './additional-info.component';
|
@ -1,25 +0,0 @@
|
||||
<div
|
||||
*transloco="
|
||||
let t;
|
||||
scope: 'claim-modification-containers';
|
||||
read: 'claimModificationContainers.documentContainer.authorityConfirmingDocumentInfo'
|
||||
"
|
||||
fxLayout="column"
|
||||
fxLayoutGap="10px"
|
||||
>
|
||||
<dsh-details-item *ngIf="authorityConfirmingDocument?.type" [title]="t('label')">
|
||||
<div *ngIf="isKnownDocumentType(authorityConfirmingDocument.type)">
|
||||
<span
|
||||
*transloco="
|
||||
let documentTypes;
|
||||
scope: 'claim-modification-containers';
|
||||
read: 'claimModificationContainers.documentContainer.authorityConfirmingDocumentInfo.documentTypes'
|
||||
"
|
||||
>{{ documentTypes(authorityConfirmingDocument.type) }}</span
|
||||
>
|
||||
</div>
|
||||
<div *ngIf="!isKnownDocumentType(authorityConfirmingDocument.type)">
|
||||
{{ authorityConfirmingDocument.type }}
|
||||
</div>
|
||||
</dsh-details-item>
|
||||
</div>
|
@ -1,21 +0,0 @@
|
||||
import { ChangeDetectionStrategy, Component, Input } from '@angular/core';
|
||||
|
||||
import { AuthorityConfirmingDocument } from '@dsh/api-codegen/questionary';
|
||||
import { AuthorityConfirmingDocumentType } from '@dsh/api/questionary/model';
|
||||
|
||||
@Component({
|
||||
selector: 'dsh-authority-confirming-document-info',
|
||||
templateUrl: 'authority-confirming-document-info.component.html',
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class AuthorityConfirmingDocumentInfoComponent {
|
||||
@Input() authorityConfirmingDocument: AuthorityConfirmingDocument;
|
||||
|
||||
isKnownDocumentType(type: string): boolean {
|
||||
return (
|
||||
type === AuthorityConfirmingDocumentType.SolePartyDecision ||
|
||||
type === AuthorityConfirmingDocumentType.MeetingOfShareholders ||
|
||||
type === AuthorityConfirmingDocumentType.MeetingOfParticipants
|
||||
);
|
||||
}
|
||||
}
|
@ -1 +0,0 @@
|
||||
export * from './authority-confirming-document-info.component';
|
@ -1,16 +0,0 @@
|
||||
<div
|
||||
*transloco="
|
||||
let t;
|
||||
scope: 'claim-modification-containers';
|
||||
read: 'claimModificationContainers.documentContainer.bankAccountInfo'
|
||||
"
|
||||
fxLayout="column"
|
||||
fxLayoutGap="20px"
|
||||
>
|
||||
<dsh-details-item *ngIf="bankAccount?.bankName" [title]="t('bankInfo')">
|
||||
{{ bankAccount?.bankName }} ({{ bankAccount?.bankBik }} / {{ bankAccount?.bankPostAccount }})
|
||||
</dsh-details-item>
|
||||
<dsh-details-item *ngIf="bankAccount?.account" [title]="t('account')">
|
||||
{{ bankAccount?.account }}
|
||||
</dsh-details-item>
|
||||
</div>
|
@ -1,12 +0,0 @@
|
||||
import { ChangeDetectionStrategy, Component, Input } from '@angular/core';
|
||||
|
||||
import { RussianBankAccount } from '@dsh/api-codegen/questionary';
|
||||
|
||||
@Component({
|
||||
selector: 'dsh-bank-account-info',
|
||||
templateUrl: 'bank-account-info.component.html',
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class BankAccountInfoComponent {
|
||||
@Input() bankAccount: RussianBankAccount;
|
||||
}
|
@ -1 +0,0 @@
|
||||
export * from './bank-account-info.component';
|
@ -1,57 +0,0 @@
|
||||
<div
|
||||
*transloco="
|
||||
let t;
|
||||
scope: 'claim-modification-containers';
|
||||
read: 'claimModificationContainers.documentContainer.beneficialOwnerInfo'
|
||||
"
|
||||
fxLayout="column"
|
||||
fxLayoutGap="10px"
|
||||
>
|
||||
<dsh-details-item [title]="t('ownershipPercentage')">
|
||||
{{ beneficialOwner?.ownershipPercentage }}
|
||||
</dsh-details-item>
|
||||
|
||||
<mat-divider></mat-divider>
|
||||
|
||||
<dsh-russian-private-entity-info
|
||||
[russianPrivateEntity]="beneficialOwner?.russianPrivateEntity"
|
||||
></dsh-russian-private-entity-info>
|
||||
|
||||
<mat-divider></mat-divider>
|
||||
|
||||
<dsh-identity-document-info [identityDocument]="beneficialOwner?.identityDocument"></dsh-identity-document-info>
|
||||
|
||||
<mat-divider></mat-divider>
|
||||
|
||||
<div fxLayout fxLayoutGap="10px">
|
||||
<dsh-details-item [title]="t('inn')" fxFlex *ngIf="beneficialOwner?.inn">
|
||||
{{ beneficialOwner?.inn }}
|
||||
</dsh-details-item>
|
||||
<dsh-details-item [title]="t('snils')" fxFlex *ngIf="beneficialOwner?.snils">
|
||||
{{ beneficialOwner?.snils }}
|
||||
</dsh-details-item>
|
||||
</div>
|
||||
|
||||
<mat-divider></mat-divider>
|
||||
|
||||
<div fxLayout *ngIf="beneficialOwner?.pdlCategory" fxLayoutGap="10px">
|
||||
<dsh-details-item fxFlex [title]="t('pdlCategory')">
|
||||
{{ beneficialOwner?.pdlCategory | yesNo }}
|
||||
</dsh-details-item>
|
||||
<dsh-details-item fxFlex *ngIf="beneficialOwner?.pdlRelationDegree" [title]="t('pdlRelationDegree')">
|
||||
{{ beneficialOwner?.pdlRelationDegree }}
|
||||
</dsh-details-item>
|
||||
</div>
|
||||
<div fxLayout fxLayoutGap="10px">
|
||||
<dsh-details-item [title]="t('usaTaxResident')" fxFlex *ngIf="residencyInfo?.usaTaxResident | yesNo">
|
||||
{{ residencyInfo?.usaTaxResident | yesNo }}
|
||||
</dsh-details-item>
|
||||
<dsh-details-item
|
||||
[title]="t('exceptUsaTaxResident')"
|
||||
fxFlex
|
||||
*ngIf="residencyInfo?.exceptUsaTaxResident | yesNo"
|
||||
>
|
||||
{{ residencyInfo?.exceptUsaTaxResident | yesNo }}
|
||||
</dsh-details-item>
|
||||
</div>
|
||||
</div>
|
@ -1,16 +0,0 @@
|
||||
import { ChangeDetectionStrategy, Component, Input } from '@angular/core';
|
||||
|
||||
import { BeneficialOwner, IndividualResidencyInfo } from '@dsh/api-codegen/questionary';
|
||||
|
||||
@Component({
|
||||
selector: 'dsh-beneficial-owner-info',
|
||||
templateUrl: 'beneficial-owner-info.component.html',
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class BeneficialOwnerInfoComponent {
|
||||
@Input() beneficialOwner: BeneficialOwner;
|
||||
|
||||
get residencyInfo(): IndividualResidencyInfo {
|
||||
return this.beneficialOwner.residencyInfo;
|
||||
}
|
||||
}
|
@ -1 +0,0 @@
|
||||
export * from './beneficial-owner-info.component';
|
@ -1,16 +0,0 @@
|
||||
<div
|
||||
*transloco="
|
||||
let t;
|
||||
scope: 'claim-modification-containers';
|
||||
read: 'claimModificationContainers.documentContainer.contactInfo'
|
||||
"
|
||||
fxLayout="column"
|
||||
fxLayoutGap="20px"
|
||||
>
|
||||
<dsh-details-item fxFlex="50" *ngIf="contactInfo?.email" [title]="t('email')">
|
||||
{{ contactInfo?.email }}
|
||||
</dsh-details-item>
|
||||
<dsh-details-item fxFlex="50" *ngIf="contactInfo?.phoneNumber" [title]="t('phoneNumber')">
|
||||
{{ contactInfo?.phoneNumber }}
|
||||
</dsh-details-item>
|
||||
</div>
|
@ -1,12 +0,0 @@
|
||||
import { ChangeDetectionStrategy, Component, Input } from '@angular/core';
|
||||
|
||||
import { ContactInfo } from '@dsh/api-codegen/questionary';
|
||||
|
||||
@Component({
|
||||
selector: 'dsh-contact-info',
|
||||
templateUrl: 'contact-info.component.html',
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class ContactInfoComponent {
|
||||
@Input() contactInfo: ContactInfo;
|
||||
}
|
@ -1 +0,0 @@
|
||||
export * from './contact-info.component';
|
@ -1,11 +0,0 @@
|
||||
<dsh-panel class="dsh-document-container-panel" color="primary">
|
||||
<dsh-panel-header (click)="expand = !expand">
|
||||
<div fxLayout="row" fxLayoutAlign="space-between center">
|
||||
{{ title }}
|
||||
<dsh-panel-header-icon [icon]="expand ? 'chevron-up' : 'chevron-down'"></dsh-panel-header-icon>
|
||||
</div>
|
||||
</dsh-panel-header>
|
||||
<dsh-panel-content *ngIf="expand">
|
||||
<ng-content></ng-content>
|
||||
</dsh-panel-content>
|
||||
</dsh-panel>
|
@ -1,3 +0,0 @@
|
||||
.dsh-document-container-panel {
|
||||
cursor: pointer;
|
||||
}
|
@ -1,12 +0,0 @@
|
||||
import { ChangeDetectionStrategy, Component, Input } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'dsh-document-container-panel',
|
||||
templateUrl: 'document-container-panel.component.html',
|
||||
styleUrls: ['document-container-panel.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class DocumentContainerPanelComponent {
|
||||
@Input() title: string;
|
||||
@Input() expand = false;
|
||||
}
|
@ -1 +0,0 @@
|
||||
export * from './document-container-panel.component';
|
@ -1,49 +0,0 @@
|
||||
<div
|
||||
*transloco="
|
||||
let t;
|
||||
scope: 'claim-modification-containers';
|
||||
read: 'claimModificationContainers.documentContainer.panelNames'
|
||||
"
|
||||
fxLayout="column"
|
||||
fxLayoutGap="16px"
|
||||
>
|
||||
<ng-container *transloco="let common">
|
||||
<div *ngIf="isLoading$ | async">{{ common('loading') }}</div>
|
||||
<div *ngIf="error$ | async">{{ common('httpError') }}</div>
|
||||
</ng-container>
|
||||
<dsh-document-container-panel
|
||||
*ngFor="let infoItem of panelInfo$ | async"
|
||||
[title]="t(infoItem.type)"
|
||||
[expand]="expandAll"
|
||||
>
|
||||
<dsh-org-info *ngIf="infoItem.type === 'orgInfo'" [orgInfo]="infoItem.item"></dsh-org-info>
|
||||
<dsh-legal-owner-info
|
||||
*ngIf="infoItem.type === 'legalOwnerInfo'"
|
||||
[legalOwnerInfo]="infoItem.item"
|
||||
></dsh-legal-owner-info>
|
||||
<dsh-individual-entity-info
|
||||
*ngIf="infoItem.type === 'individualEntityInfo'"
|
||||
[individualEntity]="infoItem.item"
|
||||
></dsh-individual-entity-info>
|
||||
<dsh-international-legal-entity-info
|
||||
*ngIf="infoItem.type === 'internationalLegalEntity'"
|
||||
[internationalLegalEntity]="infoItem.item"
|
||||
></dsh-international-legal-entity-info>
|
||||
<dsh-shop-info *ngIf="infoItem.type === 'shopInfo'" [shopInfo]="infoItem.item"></dsh-shop-info>
|
||||
<dsh-bank-account-info
|
||||
*ngIf="infoItem.type === 'bankAccountInfo'"
|
||||
[bankAccount]="infoItem.item"
|
||||
></dsh-bank-account-info>
|
||||
<dsh-international-bank-account-info
|
||||
*ngIf="infoItem.type === 'internationalBankAccountInfo'"
|
||||
[bankAccount]="infoItem.item"
|
||||
></dsh-international-bank-account-info>
|
||||
<dsh-contact-info *ngIf="infoItem.type === 'contactInfo'" [contactInfo]="infoItem.item"></dsh-contact-info>
|
||||
</dsh-document-container-panel>
|
||||
<dsh-document-container-panel
|
||||
*ngFor="let beneficialOwner of beneficialOwners$ | async; index as i"
|
||||
[title]="t('beneficialOwnerInfo', { num: i + 1 })"
|
||||
>
|
||||
<dsh-beneficial-owner-info [beneficialOwner]="beneficialOwner"></dsh-beneficial-owner-info>
|
||||
</dsh-document-container-panel>
|
||||
</div>
|
@ -1,29 +0,0 @@
|
||||
import { ChangeDetectionStrategy, Component, Input, OnChanges, SimpleChanges } from '@angular/core';
|
||||
|
||||
import { DocumentModificationUnit } from '@dsh/api-codegen/claim-management';
|
||||
|
||||
import { DocumentContainerService } from './document-container.service';
|
||||
|
||||
@Component({
|
||||
selector: 'dsh-document-container',
|
||||
templateUrl: 'document-container.component.html',
|
||||
providers: [DocumentContainerService],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class DocumentContainerComponent implements OnChanges {
|
||||
@Input() unit: DocumentModificationUnit;
|
||||
@Input() expandAll = false;
|
||||
|
||||
isLoading$ = this.documentContainerService.isLoading$;
|
||||
error$ = this.documentContainerService.error$;
|
||||
panelInfo$ = this.documentContainerService.panelInfo$;
|
||||
beneficialOwners$ = this.documentContainerService.beneficialOwners$;
|
||||
|
||||
constructor(private documentContainerService: DocumentContainerService) {}
|
||||
|
||||
ngOnChanges({ unit }: SimpleChanges) {
|
||||
if (unit && unit.currentValue) {
|
||||
this.documentContainerService.unitChange(unit.currentValue);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,58 +0,0 @@
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { NgModule } from '@angular/core';
|
||||
import { FlexLayoutModule } from '@angular/flex-layout';
|
||||
import { MatDividerModule } from '@angular/material/divider';
|
||||
import { TranslocoModule } from '@ngneat/transloco';
|
||||
|
||||
import { QuestionaryModule } from '@dsh/api/questionary';
|
||||
import { CountryCodesModule } from '@dsh/app/shared/services';
|
||||
import { LayoutModule } from '@dsh/components/layout';
|
||||
|
||||
import { AdditionalInfoComponent } from './additional-info';
|
||||
import { AuthorityConfirmingDocumentInfoComponent } from './authority-confirming-document-info';
|
||||
import { BankAccountInfoComponent } from './bank-account-info';
|
||||
import { BeneficialOwnerInfoComponent } from './beneficial-owner-info';
|
||||
import { ContactInfoComponent } from './contact-info';
|
||||
import { DocumentContainerPanelComponent } from './document-container-panel';
|
||||
import { DocumentContainerComponent } from './document-container.component';
|
||||
import { IdentityDocumentInfoComponent } from './identity-document-info';
|
||||
import { IndividualEntityInfoComponent } from './individual-entity-info';
|
||||
import { InternationalBankAccountInfoComponent } from './international-bank-account-info';
|
||||
import { InternationalLegalEntityInfoComponent } from './international-legal-entity-info';
|
||||
import { LegalOwnerInfoComponent } from './legal-owner-info';
|
||||
import { OrgInfoComponent } from './org-info';
|
||||
import { RussianPrivateEntityInfoComponent } from './russian-private-entity-info';
|
||||
import { ShopInfoComponent } from './shop-info';
|
||||
import { YesNoPipe } from './yes-no.pipe';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
CommonModule,
|
||||
LayoutModule,
|
||||
FlexLayoutModule,
|
||||
TranslocoModule,
|
||||
QuestionaryModule,
|
||||
MatDividerModule,
|
||||
CountryCodesModule,
|
||||
],
|
||||
declarations: [
|
||||
OrgInfoComponent,
|
||||
ShopInfoComponent,
|
||||
LegalOwnerInfoComponent,
|
||||
IndividualEntityInfoComponent,
|
||||
DocumentContainerComponent,
|
||||
DocumentContainerPanelComponent,
|
||||
BankAccountInfoComponent,
|
||||
AdditionalInfoComponent,
|
||||
AuthorityConfirmingDocumentInfoComponent,
|
||||
IdentityDocumentInfoComponent,
|
||||
ContactInfoComponent,
|
||||
RussianPrivateEntityInfoComponent,
|
||||
BeneficialOwnerInfoComponent,
|
||||
YesNoPipe,
|
||||
InternationalLegalEntityInfoComponent,
|
||||
InternationalBankAccountInfoComponent,
|
||||
],
|
||||
exports: [DocumentContainerComponent],
|
||||
})
|
||||
export class DocumentContainerModule {}
|
@ -1,57 +0,0 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import isEqual from 'lodash-es/isEqual';
|
||||
import { Observable, ReplaySubject, Subject } from 'rxjs';
|
||||
import { distinctUntilChanged, map, pluck, shareReplay, switchMap } from 'rxjs/operators';
|
||||
|
||||
import { DocumentModificationUnit } from '@dsh/api-codegen/claim-management';
|
||||
import { QuestionaryData } from '@dsh/api-codegen/questionary';
|
||||
import {
|
||||
isRussianIndividualEntityQuestionary,
|
||||
isRussianLegalEntityQuestionary,
|
||||
QuestionaryService,
|
||||
} from '@dsh/api/questionary';
|
||||
|
||||
import { booleanDelay, SHARE_REPLAY_CONF, takeError } from '../../../../custom-operators';
|
||||
import { PanelInfo, toPanelInfo } from './to-panel-info';
|
||||
|
||||
@Injectable()
|
||||
export class DocumentContainerService {
|
||||
private unitChange$: Subject<DocumentModificationUnit> = new ReplaySubject(1);
|
||||
private questionary$ = this.unitChange$.pipe(
|
||||
pluck('documentId'),
|
||||
distinctUntilChanged(isEqual),
|
||||
switchMap((documentId) => this.questionaryService.getQuestionary(documentId)),
|
||||
shareReplay(SHARE_REPLAY_CONF)
|
||||
);
|
||||
private questionaryData$: Observable<QuestionaryData> = this.questionary$.pipe(
|
||||
pluck('questionary', 'data'),
|
||||
shareReplay(SHARE_REPLAY_CONF)
|
||||
);
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/member-ordering
|
||||
beneficialOwners$ = this.questionary$.pipe(
|
||||
map(({ questionary }) =>
|
||||
isRussianIndividualEntityQuestionary(questionary)
|
||||
? questionary.data.contractor.individualEntity.beneficialOwners
|
||||
: isRussianLegalEntityQuestionary(questionary)
|
||||
? questionary.data.contractor.legalEntity.beneficialOwner
|
||||
: null
|
||||
),
|
||||
shareReplay(SHARE_REPLAY_CONF)
|
||||
);
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/member-ordering
|
||||
panelInfo$: Observable<PanelInfo[]> = this.questionaryData$.pipe(toPanelInfo, shareReplay(SHARE_REPLAY_CONF));
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/member-ordering
|
||||
isLoading$: Observable<boolean> = this.questionaryData$.pipe(booleanDelay(), shareReplay(SHARE_REPLAY_CONF));
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/member-ordering
|
||||
error$: Observable<any> = this.questionaryData$.pipe(takeError, shareReplay(SHARE_REPLAY_CONF));
|
||||
|
||||
constructor(private questionaryService: QuestionaryService) {}
|
||||
|
||||
unitChange(unit: DocumentModificationUnit) {
|
||||
this.unitChange$.next(unit);
|
||||
}
|
||||
}
|
@ -1,24 +0,0 @@
|
||||
<div
|
||||
*transloco="
|
||||
let t;
|
||||
scope: 'claim-modification-containers';
|
||||
read: 'claimModificationContainers.documentContainer.identityDocumentInfo'
|
||||
"
|
||||
fxLayout="column"
|
||||
fxLayoutGap="20px"
|
||||
>
|
||||
<div fxLayout="row">
|
||||
<dsh-details-item fxFlex="50" *ngIf="identityDocument?.seriesNumber" [title]="t('seriesNumber')">
|
||||
{{ identityDocument?.seriesNumber }}
|
||||
</dsh-details-item>
|
||||
<dsh-details-item fxFlex="50" *ngIf="identityDocument?.issuerCode" [title]="t('issuerCode')">
|
||||
{{ identityDocument?.issuerCode }}
|
||||
</dsh-details-item>
|
||||
</div>
|
||||
<dsh-details-item *ngIf="identityDocument?.issuedAt" [title]="t('issuedAt')">
|
||||
{{ identityDocument?.issuedAt | date }}
|
||||
</dsh-details-item>
|
||||
<dsh-details-item *ngIf="identityDocument?.issuer" [title]="t('issuer')">
|
||||
{{ identityDocument?.issuer }}
|
||||
</dsh-details-item>
|
||||
</div>
|
@ -1,12 +0,0 @@
|
||||
import { ChangeDetectionStrategy, Component, Input } from '@angular/core';
|
||||
|
||||
import { RussianDomesticPassport } from '@dsh/api-codegen/questionary';
|
||||
|
||||
@Component({
|
||||
selector: 'dsh-identity-document-info',
|
||||
templateUrl: 'identity-document-info.component.html',
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class IdentityDocumentInfoComponent {
|
||||
@Input() identityDocument: RussianDomesticPassport;
|
||||
}
|
@ -1 +0,0 @@
|
||||
export * from './identity-document-info.component';
|
@ -1,2 +0,0 @@
|
||||
export * from './document-container.module';
|
||||
export * from './document-container.component';
|
@ -1 +0,0 @@
|
||||
export * from './individual-entity-info.component';
|
@ -1,24 +0,0 @@
|
||||
<div
|
||||
*transloco="
|
||||
let t;
|
||||
scope: 'claim-modification-containers';
|
||||
read: 'claimModificationContainers.documentContainer.individualEntityInfo'
|
||||
"
|
||||
fxLayout="column"
|
||||
fxLayoutGap="20px"
|
||||
>
|
||||
<dsh-russian-private-entity-info
|
||||
[russianPrivateEntity]="individualEntity?.russianPrivateEntity"
|
||||
></dsh-russian-private-entity-info>
|
||||
<mat-divider></mat-divider>
|
||||
<dsh-identity-document-info [identityDocument]="individualEntity?.identityDocument"></dsh-identity-document-info>
|
||||
<mat-divider></mat-divider>
|
||||
<div fxLayout="row" *ngIf="individualEntity?.pdlCategory || individualEntity?.pdlRelationDegree">
|
||||
<dsh-details-item fxFlex="50" *ngIf="individualEntity?.pdlCategory" [title]="t('pdlCategory')">
|
||||
{{ t('pdlCategoryFlag') }}
|
||||
</dsh-details-item>
|
||||
<dsh-details-item fxFlex="50" *ngIf="individualEntity?.pdlRelationDegree" [title]="t('pdlRelationDegree')">
|
||||
{{ individualEntity?.pdlRelationDegree }}
|
||||
</dsh-details-item>
|
||||
</div>
|
||||
</div>
|
@ -1,12 +0,0 @@
|
||||
import { ChangeDetectionStrategy, Component, Input } from '@angular/core';
|
||||
|
||||
import { RussianIndividualEntity } from '@dsh/api-codegen/questionary';
|
||||
|
||||
@Component({
|
||||
selector: 'dsh-individual-entity-info',
|
||||
templateUrl: 'individual-entity-info.component.html',
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class IndividualEntityInfoComponent {
|
||||
@Input() individualEntity: RussianIndividualEntity;
|
||||
}
|
@ -1 +0,0 @@
|
||||
export * from './international-bank-account-info.component';
|
@ -1,38 +0,0 @@
|
||||
<div
|
||||
*transloco="
|
||||
let t;
|
||||
scope: 'claim-modification-containers';
|
||||
read: 'claimModificationContainers.documentContainer.internationalBankAccountInfo'
|
||||
"
|
||||
fxLayout="column"
|
||||
fxLayoutGap="20px"
|
||||
>
|
||||
<dsh-details-item *ngIf="bankAccount?.bank?.name" [title]="t('name')">
|
||||
{{ bankAccount.bank.name }}
|
||||
</dsh-details-item>
|
||||
<dsh-details-item *ngIf="bankAccount?.number" [title]="t('number')">
|
||||
{{ bankAccount.number }}
|
||||
</dsh-details-item>
|
||||
<dsh-details-item *ngIf="bankAccount?.bank?.country" [title]="t('country')">
|
||||
{{ getCountryCodeText(bankAccount.bank.country) }}
|
||||
</dsh-details-item>
|
||||
<dsh-details-item *ngIf="bankAccount?.bank?.address" [title]="t('address')">
|
||||
{{ bankAccount.bank.address }}
|
||||
</dsh-details-item>
|
||||
<dsh-details-item *ngIf="bankAccount?.bank?.bic" [title]="t('bic')">
|
||||
{{ bankAccount.bank.bic }}
|
||||
</dsh-details-item>
|
||||
<dsh-details-item *ngIf="bankAccount?.bank?.abaRtn" [title]="t('abaRtn')">
|
||||
{{ bankAccount.bank.abaRtn }}
|
||||
</dsh-details-item>
|
||||
<dsh-details-item *ngIf="bankAccount?.iban" [title]="t('iban')">
|
||||
{{ bankAccount.iban }}
|
||||
</dsh-details-item>
|
||||
<div *ngIf="hasCorrespondentAccount(bankAccount['correspondentAccount'])" fxLayout="column" fxLayoutGap="20px">
|
||||
<mat-divider></mat-divider>
|
||||
<div class="dsh-title">{{ t('correspondentAccount') }}</div>
|
||||
<dsh-international-bank-account-info
|
||||
[bankAccount]="bankAccount['correspondentAccount']"
|
||||
></dsh-international-bank-account-info>
|
||||
</div>
|
||||
</div>
|
@ -1,23 +0,0 @@
|
||||
import { ChangeDetectionStrategy, Component, Input } from '@angular/core';
|
||||
|
||||
import { CorrespondentAccount, InternationalBankAccount } from '@dsh/api-codegen/questionary';
|
||||
import { CountryCodesService } from '@dsh/app/shared/services/country-codes/country-codes.service';
|
||||
|
||||
@Component({
|
||||
selector: 'dsh-international-bank-account-info',
|
||||
templateUrl: 'international-bank-account-info.component.html',
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class InternationalBankAccountInfoComponent {
|
||||
@Input() bankAccount: InternationalBankAccount | CorrespondentAccount;
|
||||
|
||||
constructor(private countryCodes: CountryCodesService) {}
|
||||
|
||||
hasCorrespondentAccount(acc: CorrespondentAccount): boolean {
|
||||
return !!Object.entries(acc?.bank || {}).length;
|
||||
}
|
||||
|
||||
getCountryCodeText(code: number): string {
|
||||
return this.countryCodes.getCountryByCode(code);
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user