TD-361: Remove old claim pages (#120)

This commit is contained in:
Rinat Arsaev 2022-08-08 20:40:04 +03:00 committed by GitHub
parent 8fa78ebef3
commit 26716d7c8a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
134 changed files with 7 additions and 3336 deletions

View File

@ -9,7 +9,7 @@ import { ClaimComponent } from './claim.component';
imports: [
RouterModule.forChild([
{
path: 'party/:partyID/claim/:claimID/new',
path: 'party/:partyID/claim/:claimID',
component: ClaimComponent,
canActivate: [AppAuthGuardService],
data: {

View File

@ -23,7 +23,7 @@ import { JsonViewerModule } from '@cc/app/shared/components/json-viewer/json-vie
import { ThriftPipesModule } from '@cc/app/shared/pipes';
import { TimelineModule } from '@cc/components/timeline';
import { TimelineComponentsModule } from '../party-claim/changeset/timeline-components';
import { HumanizeDurationModule } from '../../shared/pipes/humanize-duration';
import { ClaimRoutingModule } from './claim-routing.module';
import { ClaimComponent } from './claim.component';
import { AddModificationDialogComponent } from './components/add-modification-dialog/add-modification-dialog.component';
@ -33,6 +33,8 @@ import { ModificationFormComponent } from './components/modification-form/modifi
import { ModificationUnitTimelineItemComponent } from './components/modification-unit-timeline-item/modification-unit-timeline-item.component';
import { ShopModificationTimelineItemComponent } from './components/shop-modification-timeline-item/shop-modification-timeline-item.component';
import { StatusModificationTimelineItemComponent } from './components/status-modification-timeline-item/status-modification-timeline-item.component';
import { TimelineItemHeaderComponent } from './components/timeline-item-header/timeline-item-header.component';
import { TimelineItemLoadingComponent } from './components/timeline-item-loading/timeline-item-loading.component';
@NgModule({
declarations: [
@ -44,6 +46,8 @@ import { StatusModificationTimelineItemComponent } from './components/status-mod
AddModificationDialogComponent,
ChangeStatusDialogComponent,
ModificationFormComponent,
TimelineItemHeaderComponent,
TimelineItemLoadingComponent,
],
imports: [
CommonModule,
@ -52,7 +56,6 @@ import { StatusModificationTimelineItemComponent } from './components/status-mod
RouterModule,
TimelineModule,
MatIconModule,
TimelineComponentsModule,
ThriftPipesModule,
MatExpansionModule,
JsonViewerModule,
@ -72,6 +75,7 @@ import { StatusModificationTimelineItemComponent } from './components/status-mod
MatProgressBarModule,
BaseDialogModule,
ActionsModule,
HumanizeDurationModule,
],
})
export class ClaimModule {}

View File

@ -1,7 +0,0 @@
@import './changeset/timeline-components/timeline-item-loading/timeline-item-loading-theme';
@import './party-claim-title/party-claim-title-theme';
@mixin cc-party-claim-theme($theme) {
@include cc-party-claim-title-theme($theme);
@include cc-timeline-item-loading-theme($theme);
}

View File

@ -1,27 +0,0 @@
import { Modification, UserInfo } from '@vality/domain-proto/lib/claim_management';
/* eslint-disable @typescript-eslint/naming-convention */
export enum ChangesetInfoType {
partyModification = 'partyModification',
commentModification = 'commentModification',
fileModification = 'fileModification',
documentModification = 'documentModification',
statusModification = 'statusModification',
}
export enum ChangesetInfoModificationType {
creation = 'creation',
deletion = 'deletion',
}
/* eslint-enable @typescript-eslint/naming-convention */
export interface ChangesetInfo {
createdAt: string;
modification: Modification;
userInfo: UserInfo;
type: ChangesetInfoType;
modificationType: ChangesetInfoModificationType;
hash: string;
outdated?: boolean;
removed?: boolean;
}

View File

@ -1,2 +0,0 @@
export * from './to-changeset-infos';
export * from './changeset-info';

View File

@ -1,9 +0,0 @@
import { ChangesetInfo } from './changeset-info';
export const markOutdated = (infos: ChangesetInfo[], hash: string): ChangesetInfo[] =>
infos.map((info) => {
if (info.hash === hash) {
info.outdated = true;
}
return info;
});

View File

@ -1,9 +0,0 @@
import { ChangesetInfo } from './changeset-info';
export const markRemoved = (infos: ChangesetInfo[], hash: string): ChangesetInfo[] =>
infos.map((info) => {
if (info.hash === hash) {
info.removed = true;
}
return info;
});

View File

@ -1,43 +0,0 @@
import { ModificationUnit } from '@vality/domain-proto/lib/claim_management';
import { ChangesetInfo, ChangesetInfoType } from './changeset-info';
import { toCommentModificationChangesetInfo } from './to-comment-modification-changeset-info';
import { toDocumentModificationChangesetInfo } from './to-document-modification-changeset-info';
import { toFileModificationChangesetInfo } from './to-file-modification-changeset-info';
import { toPartyModificationChangesetInfo } from './to-party-modification-changeset-info';
import { toStatusModificationChangesetInfo } from './to-status-modification-changeset-info';
const getModificationType = (unit: ModificationUnit): ChangesetInfoType | null => {
if (unit.modification.party_modification) {
return ChangesetInfoType.partyModification;
} else if (unit.modification.claim_modification.comment_modification) {
return ChangesetInfoType.commentModification;
} else if (unit.modification.claim_modification.file_modification) {
return ChangesetInfoType.fileModification;
} else if (unit.modification.claim_modification.document_modification) {
return ChangesetInfoType.documentModification;
} else if (unit.modification.claim_modification.status_modification) {
return ChangesetInfoType.statusModification;
} else {
return null;
}
};
export const toChangesetInfos = (units: ModificationUnit[]): ChangesetInfo[] =>
units.reduce((acc, cur) => {
switch (getModificationType(cur)) {
case ChangesetInfoType.partyModification:
return toPartyModificationChangesetInfo(acc, cur);
case ChangesetInfoType.commentModification:
return toCommentModificationChangesetInfo(acc, cur);
case ChangesetInfoType.fileModification:
return toFileModificationChangesetInfo(acc, cur);
case ChangesetInfoType.documentModification:
return toDocumentModificationChangesetInfo(acc, cur);
case ChangesetInfoType.statusModification:
return toStatusModificationChangesetInfo(acc, cur);
default:
console.error('Changeset infos: Unknown type', cur);
return acc;
}
}, []);

View File

@ -1,38 +0,0 @@
import { CommentModification, ModificationUnit } from '@vality/domain-proto/lib/claim_management';
import { getUnionKey } from '@cc/utils/get-union-key';
import { ChangesetInfo, ChangesetInfoModificationType, ChangesetInfoType } from './changeset-info';
import { markRemoved } from './mark-removed';
const getCommentChangesetInfoHash = (unit: ModificationUnit): string =>
`${ChangesetInfoType.commentModification}.${unit.modification.claim_modification.comment_modification.id}`;
const commentModificationType = (mod: CommentModification): ChangesetInfoModificationType => {
switch (getUnionKey(mod)) {
case 'creation':
return ChangesetInfoModificationType.creation;
case 'deletion':
return ChangesetInfoModificationType.deletion;
}
};
const makeCommentChangesetInfo = (unit: ModificationUnit): ChangesetInfo =>
({
createdAt: unit.created_at,
modification: unit.modification,
userInfo: unit.user_info,
type: ChangesetInfoType.commentModification,
hash: getCommentChangesetInfoHash(unit),
modificationType: commentModificationType(
unit.modification.claim_modification.comment_modification.modification
),
} as ChangesetInfo);
export const toCommentModificationChangesetInfo = (
infos: ChangesetInfo[],
unit: ModificationUnit
): ChangesetInfo[] => {
const commentChangesetInfo = makeCommentChangesetInfo(unit);
return [...markRemoved(infos, commentChangesetInfo.hash), commentChangesetInfo];
};

View File

@ -1,23 +0,0 @@
import { ModificationUnit } from '@vality/domain-proto/lib/claim_management';
import { ChangesetInfo, ChangesetInfoType } from './changeset-info';
import { markOutdated } from './mark-outdated';
const getDocumentChangesetInfoHash = (): string => `${ChangesetInfoType.documentModification}`;
const makeDocumentChangesetInfo = (unit: ModificationUnit): ChangesetInfo =>
({
createdAt: unit.created_at,
modification: unit.modification,
userInfo: unit.user_info,
type: ChangesetInfoType.documentModification,
hash: getDocumentChangesetInfoHash(),
} as ChangesetInfo);
export const toDocumentModificationChangesetInfo = (
infos: ChangesetInfo[],
unit: ModificationUnit
): ChangesetInfo[] => {
const documentChangesetInfo = makeDocumentChangesetInfo(unit);
return [...markOutdated(infos, documentChangesetInfo.hash), documentChangesetInfo];
};

View File

@ -1,38 +0,0 @@
import { FileModification, ModificationUnit } from '@vality/domain-proto/lib/claim_management';
import { getUnionKey } from '@cc/utils/get-union-key';
import { ChangesetInfo, ChangesetInfoModificationType, ChangesetInfoType } from './changeset-info';
import { markRemoved } from './mark-removed';
const getFileChangesetInfoHash = (unit: ModificationUnit): string =>
`${ChangesetInfoType.fileModification}.${unit.modification.claim_modification.file_modification.id}`;
const fileModificationType = (mod: FileModification): ChangesetInfoModificationType => {
switch (getUnionKey(mod)) {
case 'creation':
return ChangesetInfoModificationType.creation;
case 'deletion':
return ChangesetInfoModificationType.deletion;
}
};
const makeFileChangesetInfo = (unit: ModificationUnit): ChangesetInfo =>
({
createdAt: unit.created_at,
modification: unit.modification,
userInfo: unit.user_info,
type: ChangesetInfoType.fileModification,
hash: getFileChangesetInfoHash(unit),
modificationType: fileModificationType(
unit.modification.claim_modification.file_modification.modification
),
} as ChangesetInfo);
export const toFileModificationChangesetInfo = (
infos: ChangesetInfo[],
unit: ModificationUnit
): ChangesetInfo[] => {
const fileChangesetInfo = makeFileChangesetInfo(unit);
return [...markRemoved(infos, fileChangesetInfo.hash), fileChangesetInfo];
};

View File

@ -1,31 +0,0 @@
import { ModificationUnit } from '@vality/domain-proto/lib/claim_management';
import { getUnionKey } from '@cc/utils/get-union-key';
import { ChangesetInfo, ChangesetInfoType } from './changeset-info';
import { markOutdated } from './mark-outdated';
const getHash = (m: any, acc: string = ''): string => {
if (m.id && m.modification) {
return `${acc}.${getUnionKey(m.modification) as string}`;
}
const unionKey = getUnionKey(m) as string;
return getHash(m[unionKey], `${acc}.${unionKey}`);
};
const makePartyChangesetInfo = (unit: ModificationUnit): ChangesetInfo =>
({
createdAt: unit.created_at,
modification: unit.modification,
userInfo: unit.user_info,
type: ChangesetInfoType.partyModification,
hash: getHash(unit.modification),
} as ChangesetInfo);
export const toPartyModificationChangesetInfo = (
infos: ChangesetInfo[],
unit: ModificationUnit
): ChangesetInfo[] => {
const partyChangesetInfo = makePartyChangesetInfo(unit);
return [...markOutdated(infos, partyChangesetInfo.hash), partyChangesetInfo];
};

View File

@ -1,17 +0,0 @@
import { ModificationUnit } from '@vality/domain-proto/lib/claim_management';
import { ChangesetInfo, ChangesetInfoType } from './changeset-info';
const makeStatusChangesetInfo = (unit: ModificationUnit): ChangesetInfo =>
({
createdAt: unit.created_at,
modification: unit.modification,
userInfo: unit.user_info,
type: ChangesetInfoType.statusModification,
hash: ChangesetInfoType.statusModification,
} as ChangesetInfo);
export const toStatusModificationChangesetInfo = (
infos: ChangesetInfo[],
unit: ModificationUnit
): ChangesetInfo[] => [...infos, makeStatusChangesetInfo(unit)];

View File

@ -1,35 +0,0 @@
<form [formGroup]="changesetsFilterForm">
<mat-form-field fxFlex>
<mat-label>Changeset filters</mat-label>
<mat-select formControlName="filters" multiple>
<mat-option class="changeset-filter-option" value="outdated"
>Hide outdated changes</mat-option
>
<mat-option class="changeset-filter-option" value="removed"
>Hide removed changes</mat-option
>
<mat-optgroup label="Modification filters">
<mat-option
[value]="changesetInfoType.partyModification"
class="changeset-filter-option"
>Party mods</mat-option
>
<mat-option
[value]="changesetInfoType.fileModification"
class="changeset-filter-option"
>Files</mat-option
>
<mat-option
[value]="changesetInfoType.commentModification"
class="changeset-filter-option"
>Comments</mat-option
>
<mat-option
[value]="changesetInfoType.documentModification"
class="changeset-filter-option"
>Documents</mat-option
>
</mat-optgroup>
</mat-select>
</mat-form-field>
</form>

View File

@ -1,3 +0,0 @@
::ng-deep .mat-select-panel {
max-height: 300px !important;
}

View File

@ -1,31 +0,0 @@
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
import { ChangesetInfo, ChangesetInfoType } from '../changeset-infos';
import { ChangesetsFilterService } from './changesets-filter.service';
@Component({
selector: 'cc-changesets-filter',
templateUrl: 'changesets-filter.component.html',
styleUrls: ['changesets-filter.component.scss'],
providers: [ChangesetsFilterService],
})
export class ChangesetsFilterComponent implements OnInit {
@Input()
set changesetInfos(v: ChangesetInfo[]) {
this.changesetsFilterService.setChangesetInfos(v);
}
@Output()
filterChange: EventEmitter<ChangesetInfo[]> = new EventEmitter();
changesetsFilterForm = this.changesetsFilterService.changesetsFilterForm;
changesetInfoType = ChangesetInfoType;
constructor(private changesetsFilterService: ChangesetsFilterService) {}
ngOnInit(): void {
this.changesetsFilterService.filteredChangesetInfos$.subscribe((infos) => {
this.filterChange.emit(infos);
});
}
}

View File

@ -1,14 +0,0 @@
import { NgModule } from '@angular/core';
import { FlexModule } from '@angular/flex-layout';
import { ReactiveFormsModule } from '@angular/forms';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatSelectModule } from '@angular/material/select';
import { ChangesetsFilterComponent } from './changesets-filter.component';
@NgModule({
declarations: [ChangesetsFilterComponent],
imports: [ReactiveFormsModule, MatFormFieldModule, MatSelectModule, FlexModule],
exports: [ChangesetsFilterComponent],
})
export class ChangesetsFilterModule {}

View File

@ -1,42 +0,0 @@
import { Injectable } from '@angular/core';
import { UntypedFormBuilder } from '@angular/forms';
import { combineLatest, Subject } from 'rxjs';
import { map, shareReplay, startWith } from 'rxjs/operators';
import { ChangesetInfo, ChangesetInfoType } from '../changeset-infos';
import { infosFilter } from './infos-filter';
@Injectable()
export class ChangesetsFilterService {
private changesetInfos$ = new Subject<ChangesetInfo[]>();
// eslint-disable-next-line @typescript-eslint/member-ordering
changesetsFilterForm = this.fb.group({
filters: [
[
ChangesetInfoType.documentModification,
ChangesetInfoType.commentModification,
ChangesetInfoType.fileModification,
ChangesetInfoType.partyModification,
ChangesetInfoType.statusModification,
],
],
});
// eslint-disable-next-line @typescript-eslint/member-ordering
filteredChangesetInfos$ = combineLatest([
this.changesetInfos$,
this.changesetsFilterForm.valueChanges.pipe(startWith(this.changesetsFilterForm.value)),
]).pipe(
map(([infos, { filters }]) => infos.filter((info) => infosFilter(info, filters))),
shareReplay(1)
);
constructor(private fb: UntypedFormBuilder) {
this.filteredChangesetInfos$.subscribe();
}
setChangesetInfos(changesetInfos: ChangesetInfo[]) {
this.changesetInfos$.next(changesetInfos);
}
}

View File

@ -1 +0,0 @@
export * from './changesets-filter.module';

View File

@ -1,13 +0,0 @@
import { ChangesetInfo } from '../changeset-infos';
export const infosFilter = (info: ChangesetInfo, filters: string[]) => {
if (
filters.length === 0 ||
(info.outdated && filters.includes('outdated')) ||
(info.removed && filters.includes('removed'))
) {
return false;
} else {
return filters.includes(info.type);
}
};

View File

@ -1,39 +0,0 @@
<div fxLayout="column" fxLayoutGap="24px">
<div fxFlex fxLayout="row" fxLayoutAlign="space-between center" fxLayoutGap="16px">
<h3 class="cc-title">Changeset</h3>
<cc-changesets-filter
[changesetInfos]="changesetInfos$ | async"
fxFlex="0 1 266px"
(filterChange)="filterChange($event)"
></cc-changesets-filter>
</div>
<cc-timeline>
<cc-created-timeline-item [createdAt]="createdAt"></cc-created-timeline-item>
<ng-container
*ngFor="let info of filteredChangesetInfos; let i = index; trackBy: simpleTrackBy"
>
<cc-file-timeline-item
*ngIf="info.type === changesetInfoType.fileModification"
[changesetInfo]="info"
[menuConfig]="fileMenuConfig"
(menuItemSelected)="menuItemSelected($event, i)"
></cc-file-timeline-item>
<cc-comment-timeline-item
*ngIf="info.type === changesetInfoType.commentModification"
[changesetInfo]="info"
[menuConfig]="commentMenuConfig"
(menuItemSelected)="menuItemSelected($event, i)"
></cc-comment-timeline-item>
<cc-party-modification-timeline-item
*ngIf="info.type === changesetInfoType.partyModification"
[changesetInfo]="info"
[menuConfig]="partyModMenuConfig"
(menuItemSelected)="menuItemSelected($event, i)"
></cc-party-modification-timeline-item>
<cc-status-timeline-item
*ngIf="info.type === changesetInfoType.statusModification"
[changesetInfo]="info"
></cc-status-timeline-item>
</ng-container>
</cc-timeline>
</div>

View File

@ -1,53 +0,0 @@
import { ChangeDetectionStrategy, Component, Input } from '@angular/core';
import { PartyID } from '@vality/domain-proto';
import { ClaimChangeset } from '@vality/domain-proto/lib/claim_management';
import { BehaviorSubject } from 'rxjs';
import { ChangesetInfo, ChangesetInfoType, toChangesetInfos } from '../changeset-infos';
import { MenuConfigAction, MenuConfigItem } from '../timeline-items/menu-config';
import { ClaimChangesetService } from './claim-changeset.service';
@Component({
selector: 'cc-claim-changeset',
templateUrl: 'claim-changeset.component.html',
changeDetection: ChangeDetectionStrategy.OnPush,
providers: [ClaimChangesetService],
})
export class ClaimChangesetComponent {
@Input()
createdAt: string;
@Input()
set changeset(v: ClaimChangeset) {
this.changesetInfos$.next(toChangesetInfos(v));
}
@Input()
partyID: PartyID;
fileMenuConfig: MenuConfigItem[] = [
{ action: MenuConfigAction.deleteFile, label: 'Delete file' },
];
commentMenuConfig: MenuConfigItem[] = [
{ action: MenuConfigAction.deleteComment, label: 'Delete comment' },
];
partyModMenuConfig: MenuConfigItem[] = [];
changesetInfoType = ChangesetInfoType;
changesetInfos$ = new BehaviorSubject<ChangesetInfo[]>([]);
filteredChangesetInfos: ChangesetInfo[] = [];
constructor(private claimChangesetService: ClaimChangesetService) {}
simpleTrackBy(index: number): number {
return index;
}
filterChange($event: ChangesetInfo[]) {
this.filteredChangesetInfos = $event;
}
menuItemSelected($event: MenuConfigItem, i: number) {
this.claimChangesetService.menuItemSelected($event, this.changesetInfos$.getValue(), i);
}
}

View File

@ -1,38 +0,0 @@
import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core';
import { FlexModule } from '@angular/flex-layout';
import { MatButtonModule } from '@angular/material/button';
import { MatDialogModule } from '@angular/material/dialog';
import { PartyModificationFormsModule } from '@cc/app/shared/components';
import { TimelineModule } from '@cc/components/timeline';
import { ChangesetsFilterModule } from '../changesets-filter';
import { CommentTimelineItemModule } from '../timeline-items/comment-timeline-item/comment-timeline-item.module';
import { CreatedTimelineItemModule } from '../timeline-items/created-timeline-item';
import { FileTimelineItemModule } from '../timeline-items/file-timeline-item/file-timeline-item.module';
import { PartyModificationTimelineItemModule } from '../timeline-items/party-modification-timeline-item/party-modification-timeline-item.module';
import { StatusTimelineItemModule } from '../timeline-items/status-timeline-item/status-timeline-item.module';
import { SaveClaimChangesetService } from '../unsaved-changeset/save-claim-changeset.service';
import { ClaimChangesetComponent } from './claim-changeset.component';
@NgModule({
imports: [
FlexModule,
CommonModule,
ChangesetsFilterModule,
TimelineModule,
MatDialogModule,
MatButtonModule,
PartyModificationFormsModule,
CreatedTimelineItemModule,
FileTimelineItemModule,
CommentTimelineItemModule,
PartyModificationTimelineItemModule,
StatusTimelineItemModule,
],
declarations: [ClaimChangesetComponent],
providers: [SaveClaimChangesetService],
exports: [ClaimChangesetComponent],
})
export class ClaimChangesetModule {}

View File

@ -1,30 +0,0 @@
import { Injectable } from '@angular/core';
import { ChangesetInfo } from '../changeset-infos';
import { MenuConfigAction, MenuConfigItem } from '../timeline-items/menu-config';
import { UnsavedClaimChangesetService } from '../unsaved-changeset/unsaved-claim-changeset.service';
import { createDeleteCommentModification } from './create-delete-comment-modification';
import { createDeleteFileModification } from './create-delete-file-modification';
@Injectable()
export class ClaimChangesetService {
constructor(private unsavedClaimChangesetService: UnsavedClaimChangesetService) {}
menuItemSelected($event: MenuConfigItem, changesetInfos: ChangesetInfo[], index: number) {
const changesetInfo = changesetInfos[index];
switch ($event.action) {
case MenuConfigAction.deleteComment:
this.unsavedClaimChangesetService.addModification(
createDeleteCommentModification(changesetInfo)
);
break;
case MenuConfigAction.deleteFile:
this.unsavedClaimChangesetService.addModification(
createDeleteFileModification(changesetInfo)
);
break;
default:
console.warn('Unsupported method', $event);
}
}
}

View File

@ -1,14 +0,0 @@
import { Modification } from '@vality/domain-proto/lib/claim_management';
import { ChangesetInfo } from '../changeset-infos';
export const createDeleteCommentModification = (info: ChangesetInfo): Modification => ({
claim_modification: {
comment_modification: {
id: info.modification.claim_modification.comment_modification.id,
modification: {
deletion: {},
},
},
},
});

View File

@ -1,14 +0,0 @@
import { Modification } from '@vality/domain-proto/lib/claim_management';
import { ChangesetInfo } from '../changeset-infos';
export const createDeleteFileModification = (info: ChangesetInfo): Modification => ({
claim_modification: {
file_modification: {
id: info.modification.claim_modification.file_modification.id,
modification: {
deletion: {},
},
},
},
});

View File

@ -1,2 +0,0 @@
export * from './claim-changeset/claim-changeset.module';
export * from './unsaved-changeset/unsaved-claim-changeset.module';

View File

@ -1 +0,0 @@
export * from './timeline-components.module';

View File

@ -1,23 +0,0 @@
import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core';
import { HumanizeDurationModule } from '@cc/app/shared/pipes/humanize-duration';
import { TimelineItemErrorComponent } from './timeline-item-error/timeline-item-error.component';
import { TimelineItemHeaderComponent } from './timeline-item-header/timeline-item-header.component';
import { TimelineItemLoadingComponent } from './timeline-item-loading/timeline-item-loading.component';
@NgModule({
declarations: [
TimelineItemLoadingComponent,
TimelineItemErrorComponent,
TimelineItemHeaderComponent,
],
imports: [CommonModule, HumanizeDurationModule],
exports: [
TimelineItemLoadingComponent,
TimelineItemErrorComponent,
TimelineItemHeaderComponent,
],
})
export class TimelineComponentsModule {}

View File

@ -1,11 +0,0 @@
import { ChangeDetectionStrategy, Component, Input } from '@angular/core';
@Component({
selector: 'cc-timeline-item-error',
templateUrl: 'timeline-item-error.component.html',
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class TimelineItemErrorComponent {
@Input()
text: string;
}

View File

@ -1,17 +0,0 @@
import { Pipe, PipeTransform } from '@angular/core';
import { ChangesetInfoModificationType } from '../../changeset-infos';
@Pipe({
name: 'ccCommentActionIcon',
})
export class CommentActionIconPipe implements PipeTransform {
transform(type: ChangesetInfoModificationType): string {
return (
{
[ChangesetInfoModificationType.creation]: 'add_comment',
[ChangesetInfoModificationType.deletion]: 'clear',
} as const
)[type];
}
}

View File

@ -1,17 +0,0 @@
import { Pipe, PipeTransform } from '@angular/core';
import { ChangesetInfoModificationType } from '../../changeset-infos';
@Pipe({
name: 'ccCommentBadgeColor',
})
export class CommentBadgeColorPipe implements PipeTransform {
transform(type: ChangesetInfoModificationType): 'primary' | 'warn' | 'error' | 'success' {
return (
{
[ChangesetInfoModificationType.creation]: 'primary',
[ChangesetInfoModificationType.deletion]: null,
} as const
)[type];
}
}

View File

@ -1,5 +0,0 @@
<mat-card>
<mat-card-content>
{{ text }}
</mat-card-content>
</mat-card>

View File

@ -1,10 +0,0 @@
import { Component, Input } from '@angular/core';
@Component({
selector: 'cc-comment-content',
templateUrl: 'comment-content.component.html',
})
export class CommentContentComponent {
@Input()
text: string;
}

View File

@ -1,17 +0,0 @@
import { Pipe, PipeTransform } from '@angular/core';
import { ChangesetInfoModificationType } from '../../changeset-infos';
@Pipe({
name: 'ccCommentHeader',
})
export class CommentHeaderPipe implements PipeTransform {
transform(type: ChangesetInfoModificationType): string {
return (
{
[ChangesetInfoModificationType.creation]: 'added message',
[ChangesetInfoModificationType.deletion]: 'removed message',
} as const
)[type];
}
}

View File

@ -1,39 +0,0 @@
<cc-timeline-item>
<cc-timeline-item-title>
<cc-timeline-item-header
[createdAt]="changesetInfo.createdAt"
[removed]="changesetInfo.removed"
[text]="changesetInfo.modificationType | ccCommentHeader"
[username]="changesetInfo.userInfo.username"
></cc-timeline-item-header>
<div *ngIf="menuConfig.length > 0">
<button [matMenuTriggerFor]="menu" mat-icon-button>
<mat-icon>more_horiz</mat-icon>
</button>
<mat-menu #menu="matMenu">
<button *ngFor="let item of menuConfig" mat-menu-item (click)="action(item)">
{{ item.label }}
</button>
</mat-menu>
</div>
</cc-timeline-item-title>
<cc-timeline-item-badge
[color]="
changesetInfo.removed ? (changesetInfo.modificationType | ccCommentBadgeColor) : null
"
>
<mat-icon>{{ changesetInfo.modificationType | ccCommentActionIcon }}</mat-icon>
</cc-timeline-item-badge>
<cc-timeline-item-content fxLayout="column" fxLayoutGap="24px">
<cc-comment-content
*ngIf="message$ | async as message"
[text]="message.text"
></cc-comment-content>
<cc-timeline-item-loading *ngIf="isLoading$ | async"></cc-timeline-item-loading>
<cc-timeline-item-error
*ngIf="error$ | async as error"
[text]="error"
></cc-timeline-item-error>
</cc-timeline-item-content>
</cc-timeline-item>

View File

@ -1,30 +0,0 @@
import { ChangeDetectionStrategy, Component, Input, OnInit } from '@angular/core';
import { ChangesetInfo } from '../../changeset-infos';
import { TimelimeItemComponent } from '../timelime-item.component';
import { CommentTimelineItemService } from './comment-timeline-item.service';
@Component({
selector: 'cc-comment-timeline-item',
templateUrl: 'comment-timeline-item.component.html',
changeDetection: ChangeDetectionStrategy.OnPush,
providers: [CommentTimelineItemService],
})
export class CommentTimelineItemComponent extends TimelimeItemComponent implements OnInit {
@Input()
changesetInfo: ChangesetInfo;
isLoading$ = this.commentTimelineItemService.isLoading$;
message$ = this.commentTimelineItemService.message$;
error$ = this.commentTimelineItemService.error$;
constructor(private commentTimelineItemService: CommentTimelineItemService) {
super();
}
ngOnInit(): void {
this.commentTimelineItemService.getMessage([
this.changesetInfo.modification.claim_modification.comment_modification.id,
]);
}
}

View File

@ -1,40 +0,0 @@
import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core';
import { FlexModule } from '@angular/flex-layout';
import { MatButtonModule } from '@angular/material/button';
import { MatCardModule } from '@angular/material/card';
import { MatIconModule } from '@angular/material/icon';
import { MatMenuModule } from '@angular/material/menu';
import { TimelineModule } from '@cc/components/timeline';
import { MessagesModule } from '../../../../../thrift-services/messages';
import { TimelineComponentsModule } from '../../timeline-components';
import { CommentActionIconPipe } from './comment-action-icon.pipe';
import { CommentBadgeColorPipe } from './comment-badge-color.pipe';
import { CommentContentComponent } from './comment-content/comment-content.component';
import { CommentHeaderPipe } from './comment-header.pipe';
import { CommentTimelineItemComponent } from './comment-timeline-item.component';
@NgModule({
imports: [
MessagesModule,
TimelineModule,
MatButtonModule,
MatIconModule,
MatMenuModule,
FlexModule,
CommonModule,
MatCardModule,
TimelineComponentsModule,
],
declarations: [
CommentTimelineItemComponent,
CommentHeaderPipe,
CommentBadgeColorPipe,
CommentActionIconPipe,
CommentContentComponent,
],
exports: [CommentTimelineItemComponent],
})
export class CommentTimelineItemModule {}

View File

@ -1,41 +0,0 @@
import { Injectable } from '@angular/core';
import { ConversationId } from '@vality/messages-proto';
import { merge, of, Subject } from 'rxjs';
import { catchError, pluck, shareReplay, switchMap } from 'rxjs/operators';
import { progress } from '@cc/app/shared/custom-operators';
import { MessagesService } from '../../../../../thrift-services/messages/messages.service';
@Injectable()
export class CommentTimelineItemService {
private getConversations$ = new Subject<ConversationId[]>();
private hasError$ = new Subject<string>();
// eslint-disable-next-line @typescript-eslint/member-ordering
message$ = this.getConversations$.pipe(
switchMap((conversationIDs) =>
this.messagesService.getConversations(conversationIDs, {}).pipe(
pluck('conversations', '0', 'messages', '0'),
catchError((e) => {
this.hasError$.next(e);
return of(e);
})
)
),
shareReplay(1)
);
// eslint-disable-next-line @typescript-eslint/member-ordering
error$ = this.hasError$.asObservable();
// eslint-disable-next-line @typescript-eslint/member-ordering
isLoading$ = progress(this.getConversations$, merge(this.message$, this.hasError$));
constructor(private messagesService: MessagesService) {
this.message$.subscribe();
}
getMessage(conversationIDs: ConversationId[]) {
this.getConversations$.next(conversationIDs);
}
}

View File

@ -1,12 +0,0 @@
<cc-timeline-item>
<cc-timeline-item-title>
<cc-timeline-item-header
[createdAt]="createdAt"
[text]="'Claim created'"
></cc-timeline-item-header>
</cc-timeline-item-title>
<cc-timeline-item-badge>
<mat-icon>create</mat-icon>
</cc-timeline-item-badge>
</cc-timeline-item>

View File

@ -1,11 +0,0 @@
import { ChangeDetectionStrategy, Component, Input } from '@angular/core';
@Component({
selector: 'cc-created-timeline-item',
templateUrl: 'created-timeline-item.component.html',
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class CreatedTimelineItemComponent {
@Input()
createdAt: string;
}

View File

@ -1,14 +0,0 @@
import { NgModule } from '@angular/core';
import { MatIconModule } from '@angular/material/icon';
import { TimelineModule } from '@cc/components/timeline';
import { TimelineComponentsModule } from '../../timeline-components';
import { CreatedTimelineItemComponent } from './created-timeline-item.component';
@NgModule({
declarations: [CreatedTimelineItemComponent],
imports: [TimelineModule, TimelineComponentsModule, MatIconModule],
exports: [CreatedTimelineItemComponent],
})
export class CreatedTimelineItemModule {}

View File

@ -1 +0,0 @@
export * from './created-timeline-item.module';

View File

@ -1,15 +0,0 @@
/**
* https://github.com/sindresorhus/multi-download/blob/master/index.js
*/
export function download(url: string, name?: string): void {
const a = document.createElement('a');
a.download = name;
a.href = url;
a.style.display = 'none';
document.body.append(a);
a.click();
// Chrome requires the timeout
setTimeout(() => {
a.remove();
}, 100);
}

View File

@ -1,17 +0,0 @@
import { Pipe, PipeTransform } from '@angular/core';
import { ChangesetInfoModificationType } from '../../changeset-infos';
@Pipe({
name: 'ccFileActionIcon',
})
export class FileActionIconPipe implements PipeTransform {
transform(type: ChangesetInfoModificationType): string {
return (
{
[ChangesetInfoModificationType.creation]: 'attach_file',
[ChangesetInfoModificationType.deletion]: 'clear',
} as const
)[type];
}
}

View File

@ -1,17 +0,0 @@
import { Pipe, PipeTransform } from '@angular/core';
import { ChangesetInfoModificationType } from '../../changeset-infos';
@Pipe({
name: 'ccFileBadgeColor',
})
export class FileBadgeColorPipe implements PipeTransform {
transform(type: ChangesetInfoModificationType): 'primary' | 'warn' | 'error' | 'success' {
return (
{
[ChangesetInfoModificationType.creation]: 'primary',
[ChangesetInfoModificationType.deletion]: null,
} as const
)[type];
}
}

View File

@ -1,8 +0,0 @@
<mat-card>
<mat-card-content fxLayout="row" fxLayoutAlign="space-between">
<div class="cc-body-1">{{ fileData.file_name }}</div>
<mat-icon class="download" (click)="downloadFile(fileData.file_data_id)"
>cloud_download</mat-icon
>
</mat-card-content>
</mat-card>

View File

@ -1,22 +0,0 @@
import { ChangeDetectionStrategy, Component, Input } from '@angular/core';
import { FileID } from '@vality/domain-proto/lib/claim_management';
import { FileData } from '@vality/file-storage-proto';
import { FileTimelineItemService } from '../file-timeline-item.service';
@Component({
selector: 'cc-file-content',
templateUrl: 'file-content.component.html',
styleUrls: ['file-content.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class FileContentComponent {
@Input()
fileData: FileData;
constructor(private fileTimelineItemService: FileTimelineItemService) {}
downloadFile(fileID: FileID) {
this.fileTimelineItemService.downloadFile(fileID);
}
}

View File

@ -1,17 +0,0 @@
import { Pipe, PipeTransform } from '@angular/core';
import { ChangesetInfoModificationType } from '../../changeset-infos';
@Pipe({
name: 'ccFileHeader',
})
export class FileHeaderPipe implements PipeTransform {
transform(type: ChangesetInfoModificationType): string {
return (
{
[ChangesetInfoModificationType.creation]: 'added files',
[ChangesetInfoModificationType.deletion]: 'removed files',
} as const
)[type];
}
}

View File

@ -1,34 +0,0 @@
<cc-timeline-item>
<cc-timeline-item-title>
<cc-timeline-item-header
[createdAt]="changesetInfo.createdAt"
[removed]="changesetInfo.removed"
[text]="changesetInfo.modificationType | ccFileHeader"
[username]="changesetInfo.userInfo.username"
></cc-timeline-item-header>
<div *ngIf="menuConfig.length > 0">
<button [matMenuTriggerFor]="menu" mat-icon-button>
<mat-icon>more_horiz</mat-icon>
</button>
<mat-menu #menu="matMenu">
<button *ngFor="let item of menuConfig" mat-menu-item (click)="action(item)">
{{ item.label }}
</button>
</mat-menu>
</div>
</cc-timeline-item-title>
<cc-timeline-item-badge
[color]="changesetInfo.removed ? (changesetInfo.modificationType | ccFileBadgeColor) : null"
>
<mat-icon>{{ changesetInfo.modificationType | ccFileActionIcon }}</mat-icon>
</cc-timeline-item-badge>
<cc-timeline-item-content fxLayout="column" fxLayoutGap="24px">
<cc-file-content
*ngIf="fileData$ | async as fileData"
[fileData]="fileData"
></cc-file-content>
<cc-timeline-item-error [text]="error$ | async"></cc-timeline-item-error>
<cc-timeline-item-loading *ngIf="isLoading$ | async"></cc-timeline-item-loading>
</cc-timeline-item-content>
</cc-timeline-item>

View File

@ -1,36 +0,0 @@
import { ChangeDetectionStrategy, Component, Input, OnInit } from '@angular/core';
import { ChangesetInfo } from '../../changeset-infos';
import { TimelimeItemComponent } from '../timelime-item.component';
import { FileTimelineItemService } from './file-timeline-item.service';
@Component({
selector: 'cc-file-timeline-item',
templateUrl: 'file-timeline-item.component.html',
changeDetection: ChangeDetectionStrategy.OnPush,
providers: [FileTimelineItemService],
})
export class FileTimelineItemComponent extends TimelimeItemComponent implements OnInit {
@Input()
changesetInfo: ChangesetInfo;
isLoading$ = this.fileTimelineItemService.isLoading$;
error$ = this.fileTimelineItemService.error$;
fileData$ = this.fileTimelineItemService.fileData$;
constructor(private fileTimelineItemService: FileTimelineItemService) {
super();
}
ngOnInit() {
this.fileTimelineItemService.getFileInfo(
this.changesetInfo?.modification.claim_modification.file_modification.id
);
}
downloadFile() {
this.fileTimelineItemService.downloadFile(
this.changesetInfo.modification.claim_modification.file_modification.id
);
}
}

View File

@ -1,40 +0,0 @@
import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core';
import { FlexModule } from '@angular/flex-layout';
import { MatButtonModule } from '@angular/material/button';
import { MatCardModule } from '@angular/material/card';
import { MatIconModule } from '@angular/material/icon';
import { MatMenuModule } from '@angular/material/menu';
import { TimelineModule } from '@cc/components/timeline';
import { FileStorageModule } from '../../../../../thrift-services/file-storage';
import { TimelineComponentsModule } from '../../timeline-components';
import { FileActionIconPipe } from './file-action-icon.pipe';
import { FileBadgeColorPipe } from './file-badge-color.pipe';
import { FileContentComponent } from './file-content/file-content.component';
import { FileHeaderPipe } from './file-header.pipe';
import { FileTimelineItemComponent } from './file-timeline-item.component';
@NgModule({
imports: [
FileStorageModule,
TimelineModule,
MatIconModule,
MatMenuModule,
CommonModule,
FlexModule,
MatButtonModule,
MatCardModule,
TimelineComponentsModule,
],
declarations: [
FileTimelineItemComponent,
FileHeaderPipe,
FileBadgeColorPipe,
FileActionIconPipe,
FileContentComponent,
],
exports: [FileTimelineItemComponent],
})
export class FileTimelineItemModule {}

View File

@ -1,60 +0,0 @@
import { Injectable } from '@angular/core';
import { FileData } from '@vality/file-storage-proto';
import * as moment from 'moment';
import { merge, Observable, of, Subject } from 'rxjs';
import { catchError, filter, map, shareReplay, switchMap } from 'rxjs/operators';
import { progress } from '@cc/app/shared/custom-operators';
import { FileStorageService } from '../../../../../thrift-services/file-storage/file-storage.service';
import { download } from './download';
@Injectable()
export class FileTimelineItemService {
private getFileInfo$ = new Subject<string>();
private hasError$ = new Subject();
// eslint-disable-next-line @typescript-eslint/member-ordering
fileData$: Observable<FileData> = this.getFileInfo$.pipe(
switchMap((fileID) =>
this.fileStorageService.getFileData(fileID).pipe(
catchError((e) => {
this.hasError$.next(e);
return of(e);
})
)
),
filter((file) => Object.keys(file).length > 0),
map((file: FileData) => ({ ...file, file_name: decodeURI(file?.file_name) })),
shareReplay(1)
);
// eslint-disable-next-line @typescript-eslint/member-ordering
error$ = this.hasError$.asObservable();
// eslint-disable-next-line @typescript-eslint/member-ordering
isLoading$ = progress(this.getFileInfo$, merge(this.fileData$, this.hasError$));
constructor(private fileStorageService: FileStorageService) {
this.fileData$.subscribe();
}
getFileInfo(fileID: string) {
this.getFileInfo$.next(fileID);
}
downloadFile(fileID: string) {
this.fileStorageService
.generateDownloadUrl(fileID, moment().add(1, 'h').toISOString())
.subscribe(
(url) => {
if (typeof url === 'string') {
download(url);
} else {
this.hasError$.next('File not found');
}
},
(e) => this.hasError$.next(e)
);
}
}

View File

@ -1,14 +0,0 @@
export enum MenuConfigAction {
/* eslint-disable @typescript-eslint/naming-convention */
editPartyModification = 'editPartyModification',
deleteComment = 'deleteComment',
deleteFile = 'deleteFile',
removeUnsavedItem = 'removeUnsavedItem',
/* eslint-enable @typescript-eslint/naming-convention */
}
export interface MenuConfigItem {
action: MenuConfigAction;
label: string;
data?: any;
}

View File

@ -1 +0,0 @@
export * from './party-modification-timeline-item.component';

View File

@ -1,6 +0,0 @@
<mat-expansion-panel [expanded]="expanded">
<mat-expansion-panel-header>
<mat-panel-title>{{ modification | ccPartyModificationName }}</mat-panel-title>
</mat-expansion-panel-header>
<cc-pretty-json [cleanLook]="true" [object]="modification"></cc-pretty-json>
</mat-expansion-panel>

View File

@ -1,14 +0,0 @@
import { Component, Input } from '@angular/core';
import { PartyModification } from '@vality/domain-proto/lib/claim_management';
@Component({
selector: 'cc-party-modification-content',
templateUrl: 'party-modification-content.component.html',
})
export class PartyModificationContentComponent {
@Input()
expanded = false;
@Input()
modification: PartyModification;
}

View File

@ -1,30 +0,0 @@
<cc-timeline-item>
<cc-timeline-item-title>
<cc-timeline-item-header
[createdAt]="changesetInfo.createdAt"
[outdated]="changesetInfo.outdated"
[text]="'added party modification'"
[username]="changesetInfo.userInfo.username"
></cc-timeline-item-header>
<div *ngIf="menuConfig.length > 0">
<button [matMenuTriggerFor]="menu" mat-icon-button>
<mat-icon>more_horiz</mat-icon>
</button>
<mat-menu #menu="matMenu">
<button *ngFor="let item of menuConfig" mat-menu-item (click)="action(item)">
{{ item.label }}
</button>
</mat-menu>
</div>
</cc-timeline-item-title>
<cc-timeline-item-badge [color]="changesetInfo?.outdated ? null : 'primary'">
<mat-icon>{{ 'add' }}</mat-icon>
</cc-timeline-item-badge>
<cc-timeline-item-content fxLayout="column" fxLayoutGap="24px">
<cc-party-modification-content
[expanded]="expanded"
[modification]="changesetInfo?.modification.party_modification"
></cc-party-modification-content>
</cc-timeline-item-content>
</cc-timeline-item>

View File

@ -1,17 +0,0 @@
import { ChangeDetectionStrategy, Component, Input } from '@angular/core';
import { ChangesetInfo } from '../../changeset-infos';
import { TimelimeItemComponent } from '../timelime-item.component';
@Component({
selector: 'cc-party-modification-timeline-item',
templateUrl: 'party-modification-timeline-item.component.html',
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class PartyModificationTimelineItemComponent extends TimelimeItemComponent {
@Input()
expanded = false;
@Input()
changesetInfo: ChangesetInfo;
}

View File

@ -1,35 +0,0 @@
import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core';
import { FlexModule } from '@angular/flex-layout';
import { MatButtonModule } from '@angular/material/button';
import { MatExpansionModule } from '@angular/material/expansion';
import { MatIconModule } from '@angular/material/icon';
import { MatMenuModule } from '@angular/material/menu';
import { ApiModelPipesModule } from '@cc/app/shared/pipes';
import { PrettyJsonModule } from '@cc/components/pretty-json';
import { TimelineModule } from '@cc/components/timeline';
import { TimelineComponentsModule } from '../../timeline-components';
import { CommentTimelineItemModule } from '../comment-timeline-item/comment-timeline-item.module';
import { PartyModificationContentComponent } from './party-modification-content/party-modification-content.component';
import { PartyModificationTimelineItemComponent } from './party-modification-timeline-item.component';
@NgModule({
declarations: [PartyModificationTimelineItemComponent, PartyModificationContentComponent],
imports: [
TimelineModule,
CommentTimelineItemModule,
MatButtonModule,
MatIconModule,
MatMenuModule,
FlexModule,
MatExpansionModule,
TimelineComponentsModule,
CommonModule,
PrettyJsonModule,
ApiModelPipesModule,
],
exports: [PartyModificationTimelineItemComponent],
})
export class PartyModificationTimelineItemModule {}

View File

@ -1,5 +0,0 @@
<mat-card>
<mat-card-content>
{{ text }}
</mat-card-content>
</mat-card>

View File

@ -1,10 +0,0 @@
import { Component, Input } from '@angular/core';
@Component({
selector: 'cc-reason-content',
templateUrl: 'reason-content.component.html',
})
export class ReasonContentComponent {
@Input()
text: string;
}

View File

@ -1,25 +0,0 @@
import { Pipe, PipeTransform } from '@angular/core';
import { ClaimStatus } from '@vality/domain-proto/lib/claim_management';
import { getUnionKey } from '@cc/utils/get-union-key';
@Pipe({
name: 'ccStatusActionIcon',
})
export class StatusActionIconPipe implements PipeTransform {
transform(status: ClaimStatus): string {
switch (getUnionKey(status)) {
case 'pending_acceptance':
case 'accepted':
return 'check';
case 'revoked':
return 'block';
case 'review':
return 'double_arrow';
case 'pending':
return 'double_arrow';
case 'denied':
return 'block';
}
}
}

View File

@ -1,21 +0,0 @@
import { Pipe, PipeTransform } from '@angular/core';
import { ClaimStatus } from '@vality/domain-proto/lib/claim_management';
import { getUnionKey } from '@cc/utils/get-union-key';
@Pipe({
name: 'ccStatusBadgeColor',
})
export class StatusBadgeColorPipe implements PipeTransform {
transform(status: ClaimStatus): 'primary' | 'warn' | 'error' | 'success' {
switch (getUnionKey(status)) {
case 'pending_acceptance':
case 'accepted':
return 'success';
case 'revoked':
return 'warn';
case 'denied':
return 'error';
}
}
}

View File

@ -1,25 +0,0 @@
import { Pipe, PipeTransform } from '@angular/core';
import { ClaimStatus } from '@vality/domain-proto/lib/claim_management';
import { getUnionKey } from '@cc/utils/get-union-key';
@Pipe({
name: 'ccStatusHeader',
})
export class StatusHeaderPipe implements PipeTransform {
transform(status: ClaimStatus): string {
switch (getUnionKey(status)) {
case 'pending_acceptance':
case 'accepted':
return 'accepted claim';
case 'revoked':
return 'revoked claim';
case 'review':
return 'changed claim status to review';
case 'pending':
return 'changed claim status to pending';
case 'denied':
return 'denied claim';
}
}
}

View File

@ -1,27 +0,0 @@
<cc-timeline-item>
<cc-timeline-item-title>
<cc-timeline-item-header
[createdAt]="changesetInfo.createdAt"
[text]="
changesetInfo.modification.claim_modification.status_modification.status
| ccStatusHeader
"
[username]="changesetInfo.userInfo.username"
></cc-timeline-item-header>
</cc-timeline-item-title>
<cc-timeline-item-badge
[color]="
changesetInfo.modification.claim_modification.status_modification.status
| ccStatusBadgeColor
"
>
<mat-icon>{{
changesetInfo.modification.claim_modification.status_modification.status
| ccStatusActionIcon
}}</mat-icon>
</cc-timeline-item-badge>
<cc-timeline-item-content *ngIf="getReason() as reason" fxLayout="column" fxLayoutGap="24px">
<cc-reason-content [text]="reason"></cc-reason-content>
</cc-timeline-item-content>
</cc-timeline-item>

View File

@ -1,18 +0,0 @@
import { ChangeDetectionStrategy, Component, Input } from '@angular/core';
import { ChangesetInfo } from '../../changeset-infos';
@Component({
selector: 'cc-status-timeline-item',
templateUrl: 'status-timeline-item.component.html',
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class StatusTimelineItemComponent {
@Input()
changesetInfo: ChangesetInfo;
getReason(): string {
const { status } = this.changesetInfo.modification.claim_modification.status_modification;
return status.revoked?.reason || status.denied?.reason;
}
}

View File

@ -1,40 +0,0 @@
import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core';
import { FlexModule } from '@angular/flex-layout';
import { MatButtonModule } from '@angular/material/button';
import { MatCardModule } from '@angular/material/card';
import { MatIconModule } from '@angular/material/icon';
import { MatMenuModule } from '@angular/material/menu';
import { TimelineModule } from '@cc/components/timeline';
import { TimelineComponentsModule } from '../../timeline-components';
import { CommentTimelineItemModule } from '../comment-timeline-item/comment-timeline-item.module';
import { ReasonContentComponent } from './reason-content/reason-content.component';
import { StatusActionIconPipe } from './status-action-icon.pipe';
import { StatusBadgeColorPipe } from './status-badge-color.pipe';
import { StatusHeaderPipe } from './status-header.pipe';
import { StatusTimelineItemComponent } from './status-timeline-item.component';
@NgModule({
declarations: [
StatusTimelineItemComponent,
StatusHeaderPipe,
StatusBadgeColorPipe,
StatusActionIconPipe,
ReasonContentComponent,
],
imports: [
TimelineModule,
CommentTimelineItemModule,
MatButtonModule,
MatIconModule,
MatMenuModule,
FlexModule,
TimelineComponentsModule,
MatCardModule,
CommonModule,
],
exports: [StatusTimelineItemComponent],
})
export class StatusTimelineItemModule {}

View File

@ -1,19 +0,0 @@
import { Component, EventEmitter, Input, Output } from '@angular/core';
import { MenuConfigItem } from './menu-config';
@Component({
template: '',
selector: 'cc-timeline-item',
})
export class TimelimeItemComponent {
@Input()
menuConfig: MenuConfigItem[];
@Output()
menuItemSelected: EventEmitter<MenuConfigItem> = new EventEmitter();
action(item: MenuConfigItem) {
this.menuItemSelected.emit(item);
}
}

View File

@ -1,31 +0,0 @@
import { Injectable } from '@angular/core';
import { MatDialog } from '@angular/material/dialog';
import { Modification } from '@vality/domain-proto/lib/claim_management';
import { Observable } from 'rxjs';
import { EditUnsavedModificationComponent } from './edit-unsaved-modification/edit-unsaved-modification.component';
import { prepareModificationToEdit } from './prepare-modification-to-edit';
type PartyModificationPosition = number;
@Injectable()
export class EditClaimChangesetService {
constructor(private dialog: MatDialog) {}
edit(pos: PartyModificationPosition, mods: Modification[]): Observable<Modification[]> {
const preparedModification = prepareModificationToEdit(mods[pos].party_modification);
return new Observable((observer) => {
const d = this.dialog.open(EditUnsavedModificationComponent, {
disableClose: true,
data: preparedModification,
width: '800px',
});
d.afterClosed().subscribe((newMod) => {
if (newMod) {
mods[pos] = newMod;
}
observer.next(mods);
});
});
}
}

View File

@ -1,106 +0,0 @@
<mat-dialog-content>
<ng-container *ngIf="modType === 'contractor_modification'">
<cc-contractor
*ngIf="mod?.contractor_modification?.modification?.creation"
[form]="form"
[initialValue]="mod.contractor_modification.modification.creation"
></cc-contractor>
</ng-container>
<ng-container *ngIf="modType === 'contract_modification'">
<cc-contract-params
*ngIf="mod.contract_modification?.modification?.creation"
[form]="form"
[initialValue]="mod.contract_modification.modification.creation"
>
</cc-contract-params>
<cc-contract-payout-tool-modification-unit
*ngIf="mod?.contract_modification?.modification?.payout_tool_modification"
[form]="form"
[initialValue]="mod.contract_modification.modification.payout_tool_modification"
>
</cc-contract-payout-tool-modification-unit>
<cc-legal-agreement-binding
*ngIf="mod?.contract_modification?.modification?.legal_agreement_binding"
[form]="form"
[initialValue]="mod.contract_modification.modification.legal_agreement_binding"
>
</cc-legal-agreement-binding>
<cc-adjustment-modification-unit
*ngIf="mod?.contract_modification?.modification?.adjustment_modification"
[form]="form"
[initialValue]="mod.contract_modification.modification.adjustment_modification"
>
</cc-adjustment-modification-unit>
<cc-report-preferences
*ngIf="mod?.contract_modification?.modification?.report_preferences_modification"
[form]="form"
[initialValue]="mod.contract_modification.modification.report_preferences_modification"
>
</cc-report-preferences>
<cc-termination
*ngIf="mod?.contract_modification?.modification?.termination"
[form]="form"
[initialValue]="mod.contract_modification.modification.termination"
>
</cc-termination>
<cc-contractor-id
*ngIf="mod?.contract_modification?.modification?.contractor_modification"
[form]="form"
>
</cc-contractor-id>
</ng-container>
<ng-container *ngIf="modType === 'shop_modification'">
<cc-category-ref
*ngIf="mod?.shop_modification?.modification?.category_modification"
[form]="form"
[initialValue]="mod.shop_modification.modification.category_modification"
>
</cc-category-ref>
<cc-shop-details
*ngIf="mod?.shop_modification?.modification?.details_modification"
[form]="form"
[initialValue]="mod.shop_modification.modification.details_modification"
>
</cc-shop-details>
<cc-shop-location
*ngIf="mod?.shop_modification?.modification?.location_modification"
[form]="form"
[initialValue]="mod.shop_modification.modification.location_modification"
>
</cc-shop-location>
<cc-shop-account-creation
*ngIf="mod?.shop_modification?.modification?.shop_account_creation"
[form]="form"
[initialValue]="mod.shop_modification.modification.shop_account_creation"
>
</cc-shop-account-creation>
<cc-shop-schedule-modification
*ngIf="mod?.shop_modification?.modification?.payout_schedule_modification"
[form]="form"
[initialValue]="mod.shop_modification.modification.payout_schedule_modification"
>
</cc-shop-schedule-modification>
<cc-shop-contract-modification
*ngIf="mod?.shop_modification?.modification?.contract_modification"
[form]="form"
[initialValue]="mod.shop_modification.modification.contract_modification"
>
</cc-shop-contract-modification>
<cc-shop-payout-tool-modification
*ngIf="mod?.shop_modification?.modification?.payout_tool_modification"
[form]="form"
[initialValue]="mod.shop_modification.modification.payout_tool_modification"
>
</cc-shop-payout-tool-modification>
<cc-shop-params
*ngIf="mod?.shop_modification?.modification?.creation"
[form]="form"
[initialValue]="mod.shop_modification.modification.creation"
>
</cc-shop-params>
</ng-container>
</mat-dialog-content>
<mat-dialog-actions fxLayout="row" fxLayoutAlign="space-between center">
<button [mat-dialog-close]="false" color="default" mat-button mat-dialog-close>CANCEL</button>
<button color="primary" mat-button (click)="save()">SAVE</button>
</mat-dialog-actions>

View File

@ -1,42 +0,0 @@
import { Component, Inject } from '@angular/core';
import { UntypedFormBuilder, UntypedFormGroup } from '@angular/forms';
import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
import { PartyModification } from '@vality/domain-proto/lib/claim_management';
import { prepareModificationsToBackend } from '@cc/app/shared/components/party-modification-creator/create-modification-dialog/prepare-modifications-to-backend';
import { getUnionKey, getUnionValue } from '@cc/utils/get-union-key';
type ModificationType =
| 'contractor_modification'
| 'contract_modification'
| 'shop_modification'
| 'wallet_modification';
@Component({
templateUrl: 'edit-unsaved-modification.component.html',
})
export class EditUnsavedModificationComponent {
mod = this.data;
form: UntypedFormGroup = this.fb.group({});
modType: ModificationType = getUnionKey<PartyModification>(this.data);
constructor(
private dialogRef: MatDialogRef<EditUnsavedModificationComponent>,
private fb: UntypedFormBuilder,
@Inject(MAT_DIALOG_DATA) private data: PartyModification
) {}
save(): void {
const modificationUnit = getUnionValue(this.mod);
this.dialogRef.close({
party_modification: prepareModificationsToBackend({
[getUnionKey(this.mod)]: {
id: modificationUnit.id,
modification: {
[getUnionKey(modificationUnit.modification)]: this.form.value,
},
},
}),
});
}
}

View File

@ -1,22 +0,0 @@
import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core';
import { FlexModule } from '@angular/flex-layout';
import { MatButtonModule } from '@angular/material/button';
import { MatDialogModule } from '@angular/material/dialog';
import { PartyModificationFormsModule } from '@cc/app/shared/components';
import { EditUnsavedModificationComponent } from './edit-unsaved-modification.component';
@NgModule({
declarations: [EditUnsavedModificationComponent],
imports: [
MatDialogModule,
CommonModule,
FlexModule,
MatButtonModule,
PartyModificationFormsModule,
],
exports: [EditUnsavedModificationComponent],
})
export class EditUnsavedModificationModule {}

View File

@ -1,15 +0,0 @@
import { CountryCode } from '@vality/domain-proto';
import { PartyModification } from '@vality/domain-proto/lib/claim_management';
import cloneDeep from 'lodash-es/cloneDeep';
export const prepareModificationToEdit = (modification: PartyModification): PartyModification => {
const prepared = cloneDeep(modification);
const countryObject =
prepared?.contractor_modification?.modification?.creation?.legal_entity
?.international_legal_entity?.country;
if (countryObject && typeof countryObject === 'object') {
prepared.contractor_modification.modification.creation.legal_entity.international_legal_entity.country =
CountryCode[countryObject.id] as any;
}
return prepared;
};

View File

@ -1,40 +0,0 @@
import { Injectable } from '@angular/core';
import { MatSnackBar } from '@angular/material/snack-bar';
import { PartyID } from '@vality/domain-proto';
import { Modification } from '@vality/domain-proto/lib/claim_management';
import Int64 from '@vality/thrift-ts/lib/int64';
import { Observable, of } from 'rxjs';
import { catchError } from 'rxjs/operators';
import { ClaimManagementService } from '../../../../thrift-services/damsel/claim-management.service';
@Injectable()
export class SaveClaimChangesetService {
constructor(
private claimManagementService: ClaimManagementService,
private snackBar: MatSnackBar
) {}
save(partyID: PartyID, claimID: string, mods: Modification[]) {
return new Observable((observer) => {
if (mods.length === 0) {
observer.error('error');
}
this.claimManagementService
.updateClaim(partyID, new Int64(parseInt(claimID, 10)) as unknown as number, mods)
.pipe(catchError(() => this.handleError()))
.subscribe((e) => {
if (e) {
observer.error('error');
}
observer.next();
observer.complete();
});
});
}
private handleError() {
this.snackBar.open('An error occurred while saving new modification', 'OK');
return of('error');
}
}

View File

@ -1,40 +0,0 @@
<div *ngIf="(unsavedChangesetInfos$ | async)?.length > 0" fxLayout="column" fxLayoutGap="24px">
<div fxLayout="row" fxLayoutAlign="space-between center">
<h3 class="cc-title">Unsaved changes</h3>
<button [disabled]="inProgress$ | async" color="primary" mat-raised-button (click)="save()">
SAVE CHANGES
</button>
</div>
<cc-timeline>
<ng-container
*ngFor="
let info of unsavedChangesetInfos$ | async;
let i = index;
trackBy: simpleTrackBy
"
>
<cc-file-timeline-item
*ngIf="info.type === changesetInfoTypes.fileModification"
[changesetInfo]="info"
[menuConfig]="fileMenuConfig"
(menuItemSelected)="menuItemSelected($event, i)"
></cc-file-timeline-item>
<cc-comment-timeline-item
*ngIf="info.type === changesetInfoTypes.commentModification"
[changesetInfo]="info"
[menuConfig]="commentMenuConfig"
(menuItemSelected)="menuItemSelected($event, i)"
></cc-comment-timeline-item>
<cc-party-modification-timeline-item
*ngIf="info.type === changesetInfoTypes.partyModification"
[changesetInfo]="info"
[menuConfig]="partyModMenuConfig"
(menuItemSelected)="menuItemSelected($event, i)"
></cc-party-modification-timeline-item>
<cc-status-timeline-item
*ngIf="info.type === changesetInfoTypes.statusModification"
[changesetInfo]="info"
></cc-status-timeline-item>
</ng-container>
</cc-timeline>
</div>

View File

@ -1,82 +0,0 @@
import {
ChangeDetectionStrategy,
Component,
EventEmitter,
Input,
OnInit,
Output,
} from '@angular/core';
import { PartyID } from '@vality/domain-proto';
import { ClaimChangeset } from '@vality/domain-proto/lib/claim_management';
import { ChangesetInfoType } from '../changeset-infos';
import { MenuConfigAction, MenuConfigItem } from '../timeline-items/menu-config';
import { UnsavedClaimChangesetService } from './unsaved-claim-changeset.service';
@Component({
selector: 'cc-unsaved-claim-changeset',
templateUrl: 'unsaved-claim-changeset.component.html',
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class UnsavedClaimChangesetComponent implements OnInit {
@Input()
changeset: ClaimChangeset;
@Input()
partyID: PartyID;
@Input()
claimID: string;
@Output()
changesetUpdated = new EventEmitter();
inProgress$ = this.unsavedClaimChangesetService.inProgress$;
unsavedChangesetInfos$ = this.unsavedClaimChangesetService.unsavedChangesetInfos$;
changesetInfoTypes = ChangesetInfoType;
fileMenuConfig: MenuConfigItem[] = [
{ action: MenuConfigAction.removeUnsavedItem, label: 'Remove' },
];
commentMenuConfig: MenuConfigItem[] = [
{ action: MenuConfigAction.removeUnsavedItem, label: 'Remove' },
];
partyModMenuConfig: MenuConfigItem[] = [
{ action: MenuConfigAction.removeUnsavedItem, label: 'Remove' },
{ action: MenuConfigAction.editPartyModification, label: 'Edit' },
];
questionaryMenuConfig: MenuConfigItem[] = [
{ action: MenuConfigAction.removeUnsavedItem, label: 'Remove' },
];
constructor(private unsavedClaimChangesetService: UnsavedClaimChangesetService) {}
ngOnInit(): void {
this.unsavedClaimChangesetService.changesetUpdated$.subscribe(() => {
this.changesetUpdated.emit();
});
}
simpleTrackBy(index: number): number {
return index;
}
save(): void {
this.unsavedClaimChangesetService.save(this.partyID, this.claimID);
}
menuItemSelected($event: MenuConfigItem, i: number): void {
switch ($event.action) {
case MenuConfigAction.removeUnsavedItem:
this.unsavedClaimChangesetService.remove(i);
break;
case MenuConfigAction.editPartyModification:
this.unsavedClaimChangesetService.edit(i);
break;
default:
console.warn('Action not implemented');
}
}
}

View File

@ -1,31 +0,0 @@
import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core';
import { FlexModule } from '@angular/flex-layout';
import { MatButtonModule } from '@angular/material/button';
import { TimelineModule } from '@cc/components/timeline';
import { CommentTimelineItemModule } from '../timeline-items/comment-timeline-item/comment-timeline-item.module';
import { FileTimelineItemModule } from '../timeline-items/file-timeline-item/file-timeline-item.module';
import { PartyModificationTimelineItemModule } from '../timeline-items/party-modification-timeline-item/party-modification-timeline-item.module';
import { StatusTimelineItemModule } from '../timeline-items/status-timeline-item/status-timeline-item.module';
import { EditClaimChangesetService } from './edit-claim-changeset.service';
import { UnsavedClaimChangesetComponent } from './unsaved-claim-changeset.component';
import { UnsavedClaimChangesetService } from './unsaved-claim-changeset.service';
@NgModule({
declarations: [UnsavedClaimChangesetComponent],
imports: [
TimelineModule,
FlexModule,
MatButtonModule,
CommonModule,
FileTimelineItemModule,
CommentTimelineItemModule,
PartyModificationTimelineItemModule,
StatusTimelineItemModule,
],
providers: [EditClaimChangesetService, UnsavedClaimChangesetService],
exports: [UnsavedClaimChangesetComponent],
})
export class UnsavedClaimChangesetModule {}

View File

@ -1,117 +0,0 @@
import { Injectable } from '@angular/core';
import { PartyID } from '@vality/domain-proto';
import {
Modification,
ModificationUnit,
PartyModification,
} from '@vality/domain-proto/lib/claim_management';
import { BehaviorSubject, forkJoin, merge, Observable, of, Subject } from 'rxjs';
import { catchError, first, map, shareReplay, switchMap, tap } from 'rxjs/operators';
import { PartyModificationEmitter } from '@cc/app/shared/components';
import { progress } from '@cc/app/shared/custom-operators';
import { KeycloakTokenInfoService } from '../../../../keycloak-token-info.service';
import { ChangesetInfo, toChangesetInfos } from '../changeset-infos';
import { EditClaimChangesetService } from './edit-claim-changeset.service';
import { SaveClaimChangesetService } from './save-claim-changeset.service';
type PartyModificationPosition = number;
@Injectable()
export class UnsavedClaimChangesetService {
private save$: Subject<{ partyID: PartyID; claimID: string }> = new Subject();
private remove$: Subject<PartyModificationPosition> = new Subject();
private edit$: Subject<PartyModificationPosition> = new Subject();
private unsaved$ = new BehaviorSubject<Modification[]>([]);
private hasError$ = new Subject<boolean | void>();
// eslint-disable-next-line @typescript-eslint/member-ordering
changesetUpdated$ = new Subject<void>();
// eslint-disable-next-line @typescript-eslint/member-ordering
unsavedChangesetInfos$: Observable<ChangesetInfo[]> = this.unsaved$.pipe(
map((mods) => {
const { name } = this.keycloakTokenInfoService.decodedUserToken;
return toChangesetInfos(
mods.map(
(mod) =>
({
modification: mod,
user_info: { username: name },
} as ModificationUnit)
)
);
}),
shareReplay(1)
);
// eslint-disable-next-line @typescript-eslint/member-ordering
inProgress$ = progress(this.save$, merge(this.changesetUpdated$, this.hasError$));
constructor(
private keycloakTokenInfoService: KeycloakTokenInfoService,
private saveClaimChangesetService: SaveClaimChangesetService,
private editClaimChangesetService: EditClaimChangesetService,
private partyModificationEmitter: PartyModificationEmitter
) {
this.unsavedChangesetInfos$.subscribe();
this.remove$
.pipe(
switchMap((pos) => forkJoin([of(pos), this.unsaved$.pipe(first())])),
map(([pos, modifications]) => modifications.filter((_, i) => pos !== i))
)
.subscribe((modifications) => this.unsaved$.next(modifications));
this.save$
.pipe(
tap(() => this.hasError$.next()),
switchMap(({ partyID, claimID }) =>
this.saveClaimChangesetService
.save(partyID, claimID, this.unsaved$.getValue())
.pipe(
catchError(() => {
this.hasError$.next(true);
return of();
})
)
)
)
.subscribe(() => {
this.unsaved$.next([]);
this.changesetUpdated$.next();
});
this.edit$
.pipe(
switchMap((pos) =>
this.editClaimChangesetService.edit(pos, this.unsaved$.getValue())
)
)
.subscribe((mods) => {
this.unsaved$.next(mods);
});
this.partyModificationEmitter.modification$.subscribe(
(partyModification: PartyModification) =>
this.addModification({ party_modification: partyModification })
);
}
save(partyID: PartyID, claimID: string) {
this.save$.next({ partyID, claimID });
}
edit(pos: number) {
this.edit$.next(pos);
}
addModification(mod: Modification) {
this.unsaved$.next([...this.unsaved$.getValue(), mod]);
}
remove(pos: PartyModificationPosition) {
this.remove$.next(pos);
}
}

View File

@ -1,45 +0,0 @@
import { Injectable } from '@angular/core';
import { MatSnackBar } from '@angular/material/snack-bar';
import { PartyID } from '@vality/domain-proto';
import Int64 from '@vality/thrift-ts/lib/int64';
import { of, ReplaySubject } from 'rxjs';
import { catchError, filter, shareReplay, switchMap } from 'rxjs/operators';
import { progress } from '@cc/app/shared/custom-operators';
import { ClaimManagementService } from '../../thrift-services/damsel/claim-management.service';
@Injectable()
export class FetchClaimService {
private getClaim$: ReplaySubject<{ partyID: PartyID; claimID: string }> = new ReplaySubject();
// eslint-disable-next-line @typescript-eslint/member-ordering
claim$ = this.getClaim$.pipe(
switchMap(({ partyID, claimID }) =>
this.claimManagementService
.getClaim(partyID, new Int64(parseInt(claimID, 10)) as unknown as number)
.pipe(
catchError((e) => {
console.error(e);
this.snackBar.open('An error occurred while fetching claim', 'OK');
return of('error');
})
)
),
filter((result) => result !== 'error'),
shareReplay(1)
);
// eslint-disable-next-line @typescript-eslint/member-ordering
isLoading$ = progress(this.getClaim$, this.claim$);
constructor(
private claimManagementService: ClaimManagementService,
private snackBar: MatSnackBar
) {
this.getClaim$.subscribe();
}
getClaim(partyID: PartyID, claimID: string) {
this.getClaim$.next({ partyID, claimID });
}
}

View File

@ -1 +0,0 @@
export * from './party-claim.module';

View File

@ -1,5 +0,0 @@
<div class="cc-file-uploader" ngfSelect (filesChange)="startUploading($event)">
<button [disabled]="disabled || (inProgress$ | async)" mat-icon-button>
<mat-icon>cloud_upload</mat-icon>
</button>
</div>

View File

@ -1,3 +0,0 @@
.cc-file-uploader:hover {
cursor: pointer;
}

View File

@ -1,28 +0,0 @@
import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output } from '@angular/core';
import { Modification } from '@vality/domain-proto/lib/claim_management';
import { FileUploaderService } from './file-uploader.service';
@Component({
selector: 'cc-file-uploader',
templateUrl: 'file-uploader.component.html',
styleUrls: ['file-uploader.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
providers: [FileUploaderService],
})
export class FileUploaderComponent {
@Output()
filesUploaded: EventEmitter<Modification[]> = new EventEmitter();
@Input()
disabled: boolean;
startUploading$ = this.fileUploaderService.startUploading$;
inProgress$ = this.fileUploaderService.inProgress$;
constructor(private fileUploaderService: FileUploaderService) {}
startUploading(files: File[]) {
this.startUploading$.next(files);
}
}

View File

@ -1,15 +0,0 @@
import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core';
import { FlexModule } from '@angular/flex-layout';
import { MatButtonModule } from '@angular/material/button';
import { MatIconModule } from '@angular/material/icon';
import { ngfModule } from 'angular-file';
import { FileUploaderComponent } from './file-uploader.component';
@NgModule({
imports: [FlexModule, CommonModule, MatIconModule, MatButtonModule, ngfModule],
exports: [FileUploaderComponent],
declarations: [FileUploaderComponent],
})
export class FileUploaderModule {}

View File

@ -1,90 +0,0 @@
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { MatSnackBar } from '@angular/material/snack-bar';
import { Modification } from '@vality/domain-proto/lib/claim_management';
import { NewFileResult } from '@vality/file-storage-proto';
import { Value } from '@vality/file-storage-proto/lib/msgpack';
import * as moment from 'moment';
import { forkJoin, merge, Observable, of, Subject } from 'rxjs';
import { catchError, filter, map, shareReplay, switchMap } from 'rxjs/operators';
import { progress } from '@cc/app/shared/custom-operators';
import { FileStorageService } from '../../../../thrift-services/file-storage/file-storage.service';
import { UnsavedClaimChangesetService } from '../../changeset/unsaved-changeset/unsaved-claim-changeset.service';
@Injectable()
export class FileUploaderService {
startUploading$ = new Subject<File[]>();
filesUploadingError$ = new Subject<null>();
filesUploaded$: Observable<string> = this.startUploading$.pipe(
switchMap((files) =>
this.uploadFile(files.pop()).pipe(
catchError((e) => {
this.snackBar.open('File uploading error', 'OK');
this.filesUploadingError$.next(e);
return of('error');
})
)
),
filter((result) => result !== 'error'),
shareReplay(1)
);
inProgress$: Observable<boolean> = progress(
this.startUploading$,
merge(this.filesUploaded$, this.filesUploadingError$)
);
constructor(
private fileStorageService: FileStorageService,
private snackBar: MatSnackBar,
private http: HttpClient,
private unsavedClaimChangesetService: UnsavedClaimChangesetService
) {
this.filesUploaded$.subscribe((fileId) =>
this.unsavedClaimChangesetService.addModification(this.createModification(fileId))
);
}
uploadFile(file: File): Observable<string> {
return this.getUploadLink().pipe(
switchMap((uploadData) =>
forkJoin([
of(uploadData.file_data_id),
this.uploadFileToUrl(file, uploadData.upload_url),
])
),
map(([fileId]) => fileId)
);
}
private getUploadLink(): Observable<NewFileResult> {
return this.fileStorageService.createNewFile(
new Map<string, Value>(),
moment().add(1, 'h').toISOString()
);
}
private uploadFileToUrl(file: File, url: string): Observable<any> {
return this.http.put(url, file, {
headers: {
'Content-Disposition': `attachment;filename=${encodeURI(file.name)}`,
'Content-Type': '',
},
});
}
private createModification(id: string): Modification {
return {
claim_modification: {
file_modification: {
id,
modification: {
creation: {},
},
},
},
};
}
}

View File

@ -1 +0,0 @@
export * from './party-claim-actions.module';

View File

@ -1,12 +0,0 @@
<mat-card fxLayout="column" fxLayoutGap="24px">
<mat-card-content fxLayout="row" fxLayoutAlign="space-between center" fxLayoutGap="8px">
<cc-send-comment fxFlex="100"></cc-send-comment>
<cc-file-uploader></cc-file-uploader>
</mat-card-content>
<mat-card-actions fxLayout="row" fxLayoutAlign="space-between center">
<button [disabled]="!canChangeStatus()" mat-button (click)="changeStatus()">
CHANGE STATUS
</button>
<button mat-button (click)="addPartyModification()">ADD PARTY MODIFICATION</button>
</mat-card-actions>
</mat-card>

View File

@ -1,77 +0,0 @@
import {
ChangeDetectionStrategy,
Component,
EventEmitter,
Input,
OnDestroy,
OnInit,
Output,
} from '@angular/core';
import { PartyID } from '@vality/domain-proto';
import { ClaimChangeset, ClaimStatus } from '@vality/domain-proto/lib/claim_management';
import { map, take } from 'rxjs/operators';
import { PartyModificationCreatorDialogService } from '@cc/app/shared/components';
import { UnsavedClaimChangesetService } from '../changeset/unsaved-changeset/unsaved-claim-changeset.service';
import { StatusChangerService } from './status-changer';
import { getAvailableClaimStatuses } from './status-changer/get-available-claim-statuses';
@Component({
selector: 'cc-party-claim-actions',
templateUrl: 'party-claim-actions.component.html',
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class PartyClaimActionsComponent implements OnInit, OnDestroy {
@Input()
partyID: PartyID;
@Input()
claimID: string;
@Input()
status: ClaimStatus;
@Input()
changeset: ClaimChangeset;
@Output()
changesetUpdated = new EventEmitter();
constructor(
private unsavedClaimChangesetService: UnsavedClaimChangesetService,
private partyModificationCreatorDialogService: PartyModificationCreatorDialogService,
private statusChangerService: StatusChangerService
) {}
ngOnInit(): void {
this.statusChangerService.init();
this.statusChangerService.statusChanged$.subscribe(() => this.changesetUpdated.emit());
}
ngOnDestroy(): void {
this.statusChangerService.destroy();
}
addPartyModification() {
this.unsavedClaimChangesetService.unsavedChangesetInfos$
.pipe(
take(1),
map((infos) => infos.map((info) => info.modification))
)
.subscribe((unsaved) =>
this.partyModificationCreatorDialogService.open(this.partyID, [
...unsaved,
...this.changeset.map((item) => item.modification),
])
);
}
changeStatus() {
this.statusChangerService.changeStatus(this.partyID, this.claimID, this.status);
}
canChangeStatus(): boolean {
return getAvailableClaimStatuses(this.status).length > 0;
}
}

View File

@ -1,23 +0,0 @@
import { NgModule } from '@angular/core';
import { FlexModule } from '@angular/flex-layout';
import { MatButtonModule } from '@angular/material/button';
import { MatCardModule } from '@angular/material/card';
import { FileUploaderModule } from './file-uploader/file-uploader.module';
import { PartyClaimActionsComponent } from './party-claim-actions.component';
import { SendCommentModule } from './send-comment/send-comment.module';
import { StatusChangerModule } from './status-changer';
@NgModule({
declarations: [PartyClaimActionsComponent],
imports: [
MatCardModule,
FlexModule,
MatButtonModule,
SendCommentModule,
FileUploaderModule,
StatusChangerModule,
],
exports: [PartyClaimActionsComponent],
})
export class PartyClaimActionsModule {}

View File

@ -1 +0,0 @@
export * from './send-comment.component';

View File

@ -1,16 +0,0 @@
<form [formGroup]="form" fxLayout="row" fxLayoutAlign="end start" fxLayoutGap="16px">
<mat-form-field fxFlex>
<mat-label>Leave a comment...</mat-label>
<input autocomplete="off" formControlName="comment" matInput type="text" />
<mat-hint>{{ form.controls.comment.value?.length || 0 }}/1000</mat-hint>
</mat-form-field>
<div class="send-comment-action">
<button
[disabled]="!form.valid || (inProgress$ | async)"
mat-icon-button
(click)="sendComment()"
>
<mat-icon>send</mat-icon>
</button>
</div>
</form>

Some files were not shown because too many files have changed in this diff Show More