mirror of
https://github.com/valitydev/control-center.git
synced 2024-11-06 02:25:17 +00:00
Revert claim-mgt (#99)
This commit is contained in:
parent
a1ee82a491
commit
a84912a68f
2
Jenkinsfile
vendored
2
Jenkinsfile
vendored
@ -16,7 +16,7 @@ build('control-center', 'docker-host') {
|
||||
runStage('init') {
|
||||
withGithubSshCredentials {
|
||||
withGithubToken {
|
||||
sh 'make wc_init'
|
||||
sh 'make wc_init'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
3
Makefile
3
Makefile
@ -22,6 +22,7 @@ BUILD_IMAGE_TAG := f3732d29a5e622aabf80542b5138b3631a726adb
|
||||
GIT_SSH_COMMAND :=
|
||||
DOCKER_RUN_OPTS = -e GIT_SSH_COMMAND='$(GIT_SSH_COMMAND)' -e NG_CLI_ANALYTICS=ci -e NPM_TOKEN='$(GITHUB_TOKEN)'
|
||||
|
||||
|
||||
CALL_W_CONTAINER := init build clean submodules
|
||||
|
||||
.PHONY: $(CALL_W_CONTAINER)
|
||||
@ -53,7 +54,7 @@ clean:
|
||||
compile-damsel: damsel-client damsel-model damsel-meta
|
||||
|
||||
damsel-client:
|
||||
@$(foreach file,domain_config payment_processing merch_stat claim_management,echo $(file); thrift -r -gen js:node,runtime_package=woody_js/dist/thrift -o ./src/app/thrift ./node_modules/damsel/proto/$(file).thrift;)
|
||||
@$(foreach file,domain_config payment_processing merch_stat,echo $(file); thrift -r -gen js:node,runtime_package=woody_js/dist/thrift -o ./src/app/thrift ./node_modules/damsel/proto/$(file).thrift;)
|
||||
|
||||
damsel-meta:
|
||||
npm run damsel-meta
|
||||
|
38
package-lock.json
generated
38
package-lock.json
generated
@ -2470,12 +2470,6 @@
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"@types/humanize-duration": {
|
||||
"version": "3.18.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/humanize-duration/-/humanize-duration-3.18.0.tgz",
|
||||
"integrity": "sha512-11QHl+GvEQ5TlCjA9xqQKNv4S0P8XFq5uHeZe2UPjngESBl7tA1tai/60eEYwWMFWIyQOl7ybarYF0B33K3Qtg==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/jasmine": {
|
||||
"version": "2.8.8",
|
||||
"resolved": "https://registry.npmjs.org/@types/jasmine/-/jasmine-2.8.8.tgz",
|
||||
@ -2491,12 +2485,6 @@
|
||||
"@types/jasmine": "*"
|
||||
}
|
||||
},
|
||||
"@types/jwt-decode": {
|
||||
"version": "2.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/jwt-decode/-/jwt-decode-2.2.1.tgz",
|
||||
"integrity": "sha512-aWw2YTtAdT7CskFyxEX2K21/zSDStuf/ikI3yBqmwpwJF0pS+/IX5DWv+1UFffZIbruP6cnT9/LAJV1gFwAT1A==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/lodash": {
|
||||
"version": "4.14.116",
|
||||
"resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.116.tgz",
|
||||
@ -2977,10 +2965,6 @@
|
||||
"tslib": "^1.7.1"
|
||||
}
|
||||
},
|
||||
"ank-proto": {
|
||||
"version": "git+ssh://git@github.com/rbkmoney/ank-proto.git#6535945971838d7dfc021aeff3248a9dac4ba28b",
|
||||
"from": "git+ssh://git@github.com/rbkmoney/ank-proto.git#6535945971838d7dfc021aeff3248a9dac4ba28b"
|
||||
},
|
||||
"ansi-colors": {
|
||||
"version": "3.2.4",
|
||||
"resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.4.tgz",
|
||||
@ -5246,8 +5230,8 @@
|
||||
"integrity": "sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk="
|
||||
},
|
||||
"damsel": {
|
||||
"version": "git+ssh://git@github.com/rbkmoney/damsel.git#5a78a602632a1dbbc5f294361d1538cff4a27040",
|
||||
"from": "git+ssh://git@github.com/rbkmoney/damsel.git#5a78a602632a1dbbc5f294361d1538cff4a27040"
|
||||
"version": "git+ssh://git@github.com/rbkmoney/damsel.git#b563890354447a5e175a9a318b33233a926a5e9c",
|
||||
"from": "git+ssh://git@github.com/rbkmoney/damsel.git#b563890354447a5e175a9a318b33233a926a5e9c"
|
||||
},
|
||||
"dashdash": {
|
||||
"version": "1.14.1",
|
||||
@ -6321,10 +6305,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"file-storage-proto": {
|
||||
"version": "git+ssh://git@github.com/rbkmoney/file-storage-proto.git#281e1ca4cea9bf32229a6c389f0dcf5d49c05a0b",
|
||||
"from": "git+ssh://git@github.com/rbkmoney/file-storage-proto.git#281e1ca4cea9bf32229a6c389f0dcf5d49c05a0b"
|
||||
},
|
||||
"fileset": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/fileset/-/fileset-2.0.3.tgz",
|
||||
@ -7046,11 +7026,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"humanize-duration": {
|
||||
"version": "3.21.0",
|
||||
"resolved": "https://registry.npmjs.org/humanize-duration/-/humanize-duration-3.21.0.tgz",
|
||||
"integrity": "sha512-7BLsrQZ2nMGeakmGDUl1pDne6/7iAdvwf1RtDLCOPHNFIHjkOVW7lcu7xHkIM9HhZAlSSO5crhC1dHvtl4dIQw=="
|
||||
},
|
||||
"humanize-ms": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz",
|
||||
@ -7920,7 +7895,8 @@
|
||||
"jwt-decode": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/jwt-decode/-/jwt-decode-2.2.0.tgz",
|
||||
"integrity": "sha1-fYa9VmefWM5qhHBKZX3TkruoGnk="
|
||||
"integrity": "sha1-fYa9VmefWM5qhHBKZX3TkruoGnk=",
|
||||
"dev": true
|
||||
},
|
||||
"karma": {
|
||||
"version": "4.3.0",
|
||||
@ -8337,10 +8313,6 @@
|
||||
"integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=",
|
||||
"dev": true
|
||||
},
|
||||
"messages-proto": {
|
||||
"version": "git+ssh://git@github.com/rbkmoney/messages-proto.git#e873358674882447bc3a2a0554db6ac08b316bec",
|
||||
"from": "git+ssh://git@github.com/rbkmoney/messages-proto.git#e873358674882447bc3a2a0554db6ac08b316bec"
|
||||
},
|
||||
"methods": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
|
||||
@ -14306,7 +14278,7 @@
|
||||
},
|
||||
"stream-http": {
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.3.1.tgz",
|
||||
"resolved": "http://registry.npmjs.org/stream-http/-/stream-http-2.3.1.tgz",
|
||||
"integrity": "sha1-fh3IcQLD4xsy5mDwTKMfI929HVI=",
|
||||
"requires": {
|
||||
"builtin-status-codes": "^2.0.0",
|
||||
|
13
package.json
13
package.json
@ -12,7 +12,6 @@
|
||||
"damsel-meta": "thrift-ts node_modules/damsel/proto -o src/assets/meta-damsel.json --json --pack --prettify",
|
||||
"machinegun-model": "thrift-ts node_modules/machinegun_proto/proto -o src/app/machinegun/gen-model -d false",
|
||||
"fistful-model": "thrift-ts node_modules/fistful-proto/proto -o src/app/fistful/gen-model -d false",
|
||||
"codegen": "npm run damsel-model; npm run damsel-meta; npm run machinegun-model; npm run fistful-model",
|
||||
"prettier": "prettier \"**/*.{html,js,ts,css,md,json,prettierrc,svg}\" --write",
|
||||
"check": "prettier \"**/*.{html,js,ts,css,md,json,prettierrc,svg}\" --list-different"
|
||||
},
|
||||
@ -34,19 +33,14 @@
|
||||
"@rbkmoney/partial-fetcher": "^1.0.4",
|
||||
"angular2-prettyjson": "3.0.1",
|
||||
"core-js": "^2.5.4",
|
||||
"damsel": "git+ssh://git@github.com/rbkmoney/damsel.git#5a78a602632a1dbbc5f294361d1538cff4a27040",
|
||||
"machinegun_proto": "git+ssh://git@github.com/rbkmoney/machinegun_proto.git#ebae56fe2b3e79e4eb34afc8cb55c9012ae989f8",
|
||||
"messages-proto": "git+ssh://git@github.com:rbkmoney/messages-proto.git#e873358674882447bc3a2a0554db6ac08b316bec",
|
||||
"file-storage-proto": "git+ssh://git@github.com:rbkmoney/file-storage-proto.git#281e1ca4cea9bf32229a6c389f0dcf5d49c05a0b",
|
||||
"ank-proto": "git+ssh://git@github.com:rbkmoney/ank-proto.git#6535945971838d7dfc021aeff3248a9dac4ba28b",
|
||||
"damsel": "git+ssh://git@github.com/rbkmoney/damsel.git#b563890354447a5e175a9a318b33233a926a5e9c",
|
||||
"fistful-proto": "git+ssh://git@github.com/rbkmoney/fistful-proto.git#6e653a244e7b2106908604c4692ee5ab4496af09",
|
||||
"hammerjs": "^2.0.8",
|
||||
"humanize-duration": "^3.21.0",
|
||||
"jsonc-parser": "^2.0.2",
|
||||
"jwt-decode": "^2.2.0",
|
||||
"keycloak-angular": "6.0.0",
|
||||
"keycloak-js": "4.5.0",
|
||||
"lodash-es": "^4.17.10",
|
||||
"machinegun_proto": "git+ssh://git@github.com/rbkmoney/machinegun_proto.git#ebae56fe2b3e79e4eb34afc8cb55c9012ae989f8",
|
||||
"moment": "^2.22.2",
|
||||
"monaco-editor": "^0.15.6",
|
||||
"rxjs": "^6.5.3",
|
||||
@ -59,16 +53,15 @@
|
||||
"@angular-devkit/build-angular": "^0.803.6",
|
||||
"@angular/cli": "^8.3.6",
|
||||
"@angular/compiler-cli": "^8.2.8",
|
||||
"@types/humanize-duration": "^3.18.0",
|
||||
"@types/jasmine": "~2.8.6",
|
||||
"@types/jasminewd2": "~2.0.3",
|
||||
"@types/jwt-decode": "^2.2.1",
|
||||
"@types/lodash-es": "^4.17.1",
|
||||
"@types/node": "~8.9.4",
|
||||
"@types/uuid": "^3.4.3",
|
||||
"codelyzer": "~4.2.1",
|
||||
"jasmine-core": "~2.99.1",
|
||||
"jasmine-spec-reporter": "~4.2.1",
|
||||
"jwt-decode": "^2.2.0",
|
||||
"karma": "^4.3.0",
|
||||
"karma-chrome-launcher": "~2.2.0",
|
||||
"karma-coverage-istanbul-reporter": "~2.0.0",
|
||||
|
@ -20,6 +20,7 @@ import {
|
||||
|
||||
import { AppComponent } from './app.component';
|
||||
import { CoreModule } from './core/core.module';
|
||||
import { ClaimsModule } from './claims/claims.module';
|
||||
import { AppRoutingModule } from './app-routing.module';
|
||||
import { ClaimModule } from './claim/claim.module';
|
||||
import { PayoutsModule } from './payouts/payouts.module';
|
||||
@ -29,7 +30,6 @@ import { PartyModule } from './party/party.module';
|
||||
import { DomainModule } from './domain';
|
||||
import { RepairingModule } from './repairing/repairing.module';
|
||||
import { DepositsModule } from './deposits/deposits.module';
|
||||
import { ClaimMgtModule } from './claim-mgt/claim-mgt.module';
|
||||
|
||||
@NgModule({
|
||||
declarations: [AppComponent],
|
||||
@ -44,8 +44,8 @@ import { ClaimMgtModule } from './claim-mgt/claim-mgt.module';
|
||||
MatMenuModule,
|
||||
MatSidenavModule,
|
||||
MatListModule,
|
||||
ClaimsModule,
|
||||
ClaimModule,
|
||||
ClaimMgtModule,
|
||||
PayoutsModule,
|
||||
PaymentAdjustmentModule,
|
||||
PartiesModule,
|
||||
|
@ -1,28 +0,0 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { RouterModule } from '@angular/router';
|
||||
import { AppAuthGuardService } from '../app-auth-guard.service';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
RouterModule.forChild([
|
||||
{
|
||||
path: 'claims',
|
||||
loadChildren: () => import('./claims').then(m => m.ClaimsModule),
|
||||
canActivate: [AppAuthGuardService],
|
||||
data: {
|
||||
roles: ['claim:get']
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'party',
|
||||
loadChildren: () => import('./claim').then(m => m.ClaimModule),
|
||||
canActivate: [AppAuthGuardService],
|
||||
data: {
|
||||
roles: ['claim:get']
|
||||
}
|
||||
}
|
||||
])
|
||||
],
|
||||
exports: [RouterModule]
|
||||
})
|
||||
export class ClaimMgtRouting {}
|
@ -1,7 +0,0 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { ClaimMgtRouting } from './claim-mgt-routing.module';
|
||||
|
||||
@NgModule({
|
||||
imports: [ClaimMgtRouting]
|
||||
})
|
||||
export class ClaimMgtModule {}
|
@ -1,21 +0,0 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { RouterModule } from '@angular/router';
|
||||
import { AppAuthGuardService } from '../../app-auth-guard.service';
|
||||
import { ClaimComponent } from './claim.component';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
RouterModule.forChild([
|
||||
{
|
||||
path: ':party_id/claim/:claim_id',
|
||||
component: ClaimComponent,
|
||||
canActivate: [AppAuthGuardService],
|
||||
data: {
|
||||
roles: ['claim:get']
|
||||
}
|
||||
}
|
||||
])
|
||||
],
|
||||
exports: [RouterModule]
|
||||
})
|
||||
export class ClaimRoutingModule {}
|
@ -1,4 +0,0 @@
|
||||
<cc-card-container *ngIf="(claim$ | async) as claim">
|
||||
<cc-claim-details [claim]="claim"></cc-claim-details>
|
||||
<cc-claim-conversation [claim]="claim"></cc-claim-conversation>
|
||||
</cc-card-container>
|
@ -1,19 +0,0 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
|
||||
import { ClaimService } from './claim.service';
|
||||
|
||||
@Component({
|
||||
templateUrl: 'claim.component.html',
|
||||
providers: [ClaimService]
|
||||
})
|
||||
export class ClaimComponent {
|
||||
claim$ = this.claimService.claim$;
|
||||
|
||||
constructor(private route: ActivatedRoute, private claimService: ClaimService) {
|
||||
this.route.params.subscribe(params => {
|
||||
const { party_id, claim_id } = params;
|
||||
this.claimService.getClaim(party_id, Number(claim_id));
|
||||
});
|
||||
}
|
||||
}
|
@ -1,25 +0,0 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { MatCardModule } from '@angular/material';
|
||||
import { FlexModule } from '@angular/flex-layout';
|
||||
|
||||
import { ClaimComponent } from './claim.component';
|
||||
import { ClaimRoutingModule } from './claim-routing.module';
|
||||
import { SharedModule } from '../../shared/shared.module';
|
||||
import { ClaimManagementService } from '../../thrift/claim-management.service';
|
||||
import { DetailsComponent } from './details/details.component';
|
||||
import { ConversationModule } from './conversation/conversation.module';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
ClaimRoutingModule,
|
||||
SharedModule,
|
||||
CommonModule,
|
||||
MatCardModule,
|
||||
FlexModule,
|
||||
ConversationModule
|
||||
],
|
||||
declarations: [ClaimComponent, DetailsComponent],
|
||||
providers: [ClaimManagementService]
|
||||
})
|
||||
export class ClaimModule {}
|
@ -1,26 +0,0 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Subject } from 'rxjs';
|
||||
import { MatSnackBar } from '@angular/material';
|
||||
|
||||
import { ClaimManagementService } from '../../thrift/claim-management.service';
|
||||
import { Claim } from '../../gen-damsel/claim_management';
|
||||
|
||||
@Injectable()
|
||||
export class ClaimService {
|
||||
claim$: Subject<Claim> = new Subject();
|
||||
|
||||
constructor(
|
||||
private claimManagementService: ClaimManagementService,
|
||||
private snackBar: MatSnackBar
|
||||
) {}
|
||||
|
||||
getClaim(partyID: string, claimID: number) {
|
||||
this.claimManagementService.getClaim(partyID, claimID).subscribe(
|
||||
claim => this.claim$.next(claim),
|
||||
e => {
|
||||
console.error(e);
|
||||
this.snackBar.open('An error occurred while claim accepting', 'OK');
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
import { Pipe, PipeTransform } from '@angular/core';
|
||||
|
||||
import { TimelineAction } from './to-timeline-info/model';
|
||||
|
||||
@Pipe({
|
||||
name: 'actionIcon'
|
||||
})
|
||||
export class ActionIconPipe implements PipeTransform {
|
||||
transform(action: TimelineAction): string {
|
||||
return ({
|
||||
[TimelineAction.statusPending]: 'visibility',
|
||||
[TimelineAction.statusReview]: 'forward',
|
||||
[TimelineAction.statusRevoked]: 'close',
|
||||
[TimelineAction.statusDenied]: 'close',
|
||||
[TimelineAction.statusAccepted]: 'done',
|
||||
[TimelineAction.filesAdded]: 'attach_file',
|
||||
[TimelineAction.commentAdded]: 'mode_comment',
|
||||
[TimelineAction.changesAdded]: 'add'
|
||||
} as const)[action];
|
||||
}
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
import { Pipe, PipeTransform } from '@angular/core';
|
||||
|
||||
import { TimelineAction } from './to-timeline-info/model';
|
||||
|
||||
@Pipe({
|
||||
name: 'actionName'
|
||||
})
|
||||
export class ActionNamePipe implements PipeTransform {
|
||||
transform(action: TimelineAction): string {
|
||||
return ({
|
||||
[TimelineAction.statusPending]: 'Changed status to Pending',
|
||||
[TimelineAction.statusReview]: 'Changed status to Review',
|
||||
[TimelineAction.statusRevoked]: 'Changed status to Revoked',
|
||||
[TimelineAction.statusDenied]: 'Changed status to Denied',
|
||||
[TimelineAction.statusAccepted]: 'Changed status to Accepted',
|
||||
[TimelineAction.filesAdded]: 'Files added',
|
||||
[TimelineAction.commentAdded]: 'Comment added',
|
||||
[TimelineAction.changesAdded]: 'Changes added'
|
||||
} as const)[action];
|
||||
}
|
||||
}
|
@ -1,34 +0,0 @@
|
||||
<cc-timeline>
|
||||
<cc-timeline-item *ngFor="let item of timelineInfo">
|
||||
<cc-timeline-item-title>
|
||||
<span>
|
||||
{{ item.action | actionName }} by {{ item.user_info.username }} at
|
||||
{{ item.created_at | date: 'dd.MM.yyyy HH:mm:ss' }} ({{
|
||||
item.created_at | humanizedDuration: { largest: 1, hasAgoEnding: true }
|
||||
}})
|
||||
</span>
|
||||
</cc-timeline-item-title>
|
||||
<cc-timeline-item-badge>
|
||||
<mat-icon>{{ item.action | actionIcon }}</mat-icon>
|
||||
</cc-timeline-item-badge>
|
||||
<cc-timeline-item-content
|
||||
*ngIf="item.modifications.length !== 0"
|
||||
fxLayout="column"
|
||||
fxLayoutGap="20px"
|
||||
>
|
||||
<mat-expansion-panel *ngFor="let modification of item.modifications">
|
||||
<mat-expansion-panel-header>
|
||||
<mat-panel-title> {{ getKey(modification) }} </mat-panel-title>
|
||||
<mat-panel-description>
|
||||
{{
|
||||
modification.claim_modification
|
||||
? getKey(modification.claim_modification)
|
||||
: getKey(modification.party_modification)
|
||||
}}
|
||||
</mat-panel-description>
|
||||
</mat-expansion-panel-header>
|
||||
<cc-pretty-json [object]="modification"></cc-pretty-json>
|
||||
</mat-expansion-panel>
|
||||
</cc-timeline-item-content>
|
||||
</cc-timeline-item>
|
||||
</cc-timeline>
|
@ -1,27 +0,0 @@
|
||||
import { Component, Input, OnChanges, SimpleChanges } from '@angular/core';
|
||||
|
||||
import { Claim } from '../../../gen-damsel/claim_management';
|
||||
import { toTimelineInfo } from './to-timeline-info';
|
||||
import { TimelineItemInfo } from './to-timeline-info/model';
|
||||
import { getUnionKey } from '../../../shared/get-union-key';
|
||||
|
||||
@Component({
|
||||
selector: 'cc-claim-conversation',
|
||||
templateUrl: 'conversation.component.html'
|
||||
})
|
||||
export class ConversationComponent implements OnChanges {
|
||||
@Input() claim: Claim;
|
||||
|
||||
timelineInfo: TimelineItemInfo[] = [];
|
||||
|
||||
ngOnChanges(changes: SimpleChanges) {
|
||||
const { currentValue } = changes.claim;
|
||||
if (currentValue) {
|
||||
this.timelineInfo = toTimelineInfo(currentValue.changeset);
|
||||
}
|
||||
}
|
||||
|
||||
getKey(u: any): string {
|
||||
return getUnionKey(u);
|
||||
}
|
||||
}
|
@ -1,42 +0,0 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { FlexLayoutModule } from '@angular/flex-layout';
|
||||
import {
|
||||
MatFormFieldModule,
|
||||
MatInputModule,
|
||||
MatIconModule,
|
||||
MatButtonModule,
|
||||
MatExpansionModule
|
||||
} from '@angular/material';
|
||||
import { ReactiveFormsModule } from '@angular/forms';
|
||||
import { LayoutModule } from '@angular/cdk/layout';
|
||||
|
||||
import { ConversationComponent } from './conversation.component';
|
||||
import { ActionIconPipe } from './action-icon.pipe';
|
||||
import { TimelineModule } from '../../../shared/components/timeline';
|
||||
import { SharedModule } from '../../../shared/shared.module';
|
||||
import { ActionNamePipe } from './action-name.pipe';
|
||||
import { MonacoEditorModule } from '../../../monaco-editor';
|
||||
import { HumanizeDurationModule } from '../../../shared/humanize-duration';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
LayoutModule,
|
||||
MatButtonModule,
|
||||
FlexLayoutModule,
|
||||
MatFormFieldModule,
|
||||
MatInputModule,
|
||||
TimelineModule,
|
||||
MatIconModule,
|
||||
SharedModule,
|
||||
CommonModule,
|
||||
ReactiveFormsModule,
|
||||
SharedModule,
|
||||
MatExpansionModule,
|
||||
MonacoEditorModule,
|
||||
HumanizeDurationModule
|
||||
],
|
||||
declarations: [ConversationComponent, ActionIconPipe, ActionNamePipe],
|
||||
exports: [ConversationComponent]
|
||||
})
|
||||
export class ConversationModule {}
|
@ -1,38 +0,0 @@
|
||||
import { TimelineAction } from './model';
|
||||
import { ClaimModification, StatusModificationUnit } from '../../../../gen-damsel/claim_management';
|
||||
import { getUnionKey } from '../../../../shared/get-union-key';
|
||||
import { ClaimStatus } from '../../../../papi/model/claim-statuses';
|
||||
|
||||
function getStatusModificationTimelineAction(unit: StatusModificationUnit): TimelineAction | null {
|
||||
const Status = ClaimStatus;
|
||||
switch (getUnionKey(unit.status)) {
|
||||
case Status.accepted:
|
||||
return TimelineAction.statusAccepted;
|
||||
case Status.denied:
|
||||
return TimelineAction.statusDenied;
|
||||
case Status.pending:
|
||||
return TimelineAction.statusPending;
|
||||
case Status.review:
|
||||
return TimelineAction.statusReview;
|
||||
case Status.revoked:
|
||||
return TimelineAction.statusRevoked;
|
||||
case Status.pending_acceptance:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
export function getClaimModificationTimelineAction(m: ClaimModification): TimelineAction | null {
|
||||
switch (getUnionKey(m)) {
|
||||
case 'document_modification':
|
||||
return TimelineAction.changesAdded;
|
||||
case 'status_modification':
|
||||
return getStatusModificationTimelineAction(
|
||||
m.status_modification as StatusModificationUnit
|
||||
);
|
||||
case 'file_modification':
|
||||
return TimelineAction.filesAdded;
|
||||
case 'comment_modification':
|
||||
return TimelineAction.commentAdded;
|
||||
}
|
||||
throw new Error(`Unknown claimModification: ${m}`);
|
||||
}
|
@ -1 +0,0 @@
|
||||
export * from './to-timeline-info';
|
@ -1,2 +0,0 @@
|
||||
export * from './timeline-item-info';
|
||||
export * from './timeline-action';
|
@ -1,10 +0,0 @@
|
||||
export enum TimelineAction {
|
||||
changesAdded = 'changesAdded',
|
||||
filesAdded = 'filesAdded',
|
||||
commentAdded = 'commentAdded',
|
||||
statusReview = 'statusReview',
|
||||
statusPending = 'statusPending',
|
||||
statusDenied = 'statusDenied',
|
||||
statusRevoked = 'statusRevoked',
|
||||
statusAccepted = 'statusAccepted'
|
||||
}
|
@ -1,9 +0,0 @@
|
||||
import { TimelineAction } from './timeline-action';
|
||||
import { Modification, UserInfo } from '../../../../../gen-damsel/claim_management';
|
||||
|
||||
export interface TimelineItemInfo {
|
||||
action: TimelineAction;
|
||||
user_info: UserInfo;
|
||||
created_at: string;
|
||||
modifications: Modification[];
|
||||
}
|
@ -1,82 +0,0 @@
|
||||
import {
|
||||
ClaimModification,
|
||||
Modification,
|
||||
ModificationUnit
|
||||
} from '../../../../gen-damsel/claim_management';
|
||||
import { TimelineAction, TimelineItemInfo } from './model';
|
||||
import { sortUnitsByCreatedAtAsc } from '../../../../shared/utils';
|
||||
import { getUnionKey } from '../../../../shared/get-union-key';
|
||||
import { getClaimModificationTimelineAction } from './get-claim-modification-timeline-action';
|
||||
|
||||
const isSame = (x: TimelineItemInfo, y: TimelineItemInfo): boolean =>
|
||||
x.action === y.action && x.user_info.type === y.user_info.type;
|
||||
|
||||
const getUnitTimelineAction = (modification: Modification): TimelineAction | null => {
|
||||
switch (getUnionKey(modification)) {
|
||||
case 'claim_modification':
|
||||
return getClaimModificationTimelineAction(
|
||||
modification.claim_modification as ClaimModification
|
||||
);
|
||||
case 'party_modification':
|
||||
return TimelineAction.changesAdded;
|
||||
}
|
||||
};
|
||||
|
||||
const toTimelineInfoModifications = (
|
||||
action: TimelineAction,
|
||||
modification: Modification
|
||||
): Modification[] => {
|
||||
switch (action) {
|
||||
case 'changesAdded':
|
||||
case 'filesAdded':
|
||||
case 'commentAdded':
|
||||
return [modification];
|
||||
default:
|
||||
return [];
|
||||
}
|
||||
};
|
||||
|
||||
const concatLastItem = (
|
||||
acc: TimelineItemInfo[],
|
||||
updateItem: TimelineItemInfo
|
||||
): TimelineItemInfo[] =>
|
||||
acc.map((accItem, accItemIndex) =>
|
||||
accItemIndex === acc.length - 1
|
||||
? {
|
||||
...updateItem,
|
||||
modifications: accItem.modifications.concat(updateItem.modifications)
|
||||
}
|
||||
: accItem
|
||||
);
|
||||
|
||||
const acceptTimelineItem = (
|
||||
acc: TimelineItemInfo[],
|
||||
{ created_at, modification, user_info }: ModificationUnit
|
||||
): TimelineItemInfo[] => {
|
||||
const action = getUnitTimelineAction(modification);
|
||||
if (action === null) {
|
||||
return acc;
|
||||
}
|
||||
const modifications = toTimelineInfoModifications(action, modification);
|
||||
const result = {
|
||||
action,
|
||||
user_info,
|
||||
created_at: created_at as string,
|
||||
modifications
|
||||
};
|
||||
if (acc.length !== 0 && modifications.length !== 0) {
|
||||
const lastItem = acc[acc.length - 1];
|
||||
if (isSame(result, lastItem)) {
|
||||
return concatLastItem(acc, result);
|
||||
}
|
||||
}
|
||||
return acc.concat(result);
|
||||
};
|
||||
|
||||
export const toTimelineInfo = (units: ModificationUnit[]): TimelineItemInfo[] => {
|
||||
if (!units || units.length === 0) {
|
||||
return [];
|
||||
}
|
||||
const sortedUnits = sortUnitsByCreatedAtAsc(units);
|
||||
return sortedUnits.reduce(acceptTimelineItem, []);
|
||||
};
|
@ -1,33 +0,0 @@
|
||||
<mat-card *ngIf="claim">
|
||||
<mat-card-subtitle>Claim details</mat-card-subtitle>
|
||||
<mat-card-content>
|
||||
<div fxFlex="50" fxLayout="column" fxLayoutGap="10px">
|
||||
<div fxLayout="row" fxLayout.xs="column">
|
||||
<label fxFlex="20">Claim ID:</label>
|
||||
<div>{{ claim.id }}</div>
|
||||
</div>
|
||||
<div fxLayout="row" fxLayout.xs="column">
|
||||
<label fxFlex="20">Status:</label>
|
||||
<div>{{ extractClaimStatus(claim.status) }}</div>
|
||||
</div>
|
||||
<div fxLayout="row" fxLayout.xs="column">
|
||||
<label fxFlex="20">Revision:</label>
|
||||
<div>{{ claim.revision }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div fxFlex="50" fxLayout="column" fxLayoutGap="10px">
|
||||
<div fxLayout="row" fxLayout.xs="column">
|
||||
<label fxFlex="20">Party ID:</label>
|
||||
<div>{{ claim.party_id }}</div>
|
||||
</div>
|
||||
<div fxLayout="row" fxLayout.xs="column">
|
||||
<label fxFlex="20">Created At:</label>
|
||||
<div>{{ claim.created_at | date: 'dd.MM.yyyy HH:mm:ss' }}</div>
|
||||
</div>
|
||||
<div fxLayout="row" fxLayout.xs="column">
|
||||
<label fxFlex="20">Updated At:</label>
|
||||
<div>{{ claim.updated_at | date: 'dd.MM.yyyy HH:mm:ss' }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</mat-card-content>
|
||||
</mat-card>
|
@ -1,16 +0,0 @@
|
||||
import { Component, Input } from '@angular/core';
|
||||
|
||||
import { Claim, ClaimStatus } from '../../../gen-damsel/claim_management';
|
||||
import { extractClaimStatus } from '../../../shared/extract-claim-status';
|
||||
|
||||
@Component({
|
||||
selector: 'cc-claim-details',
|
||||
templateUrl: 'details.component.html'
|
||||
})
|
||||
export class DetailsComponent {
|
||||
@Input() claim: Claim;
|
||||
|
||||
extractClaimStatus(status: ClaimStatus) {
|
||||
return extractClaimStatus(status);
|
||||
}
|
||||
}
|
@ -1 +0,0 @@
|
||||
export * from './claim.module';
|
@ -1,29 +0,0 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
|
||||
import { ClaimsService } from './claims.service';
|
||||
import { SearchFormValue } from './search-form/search-form-value';
|
||||
import { ClaimStatus } from '../../papi/model/claim-statuses';
|
||||
|
||||
@Component({
|
||||
templateUrl: 'claims.component.html',
|
||||
styleUrls: []
|
||||
})
|
||||
export class ClaimsComponent implements OnInit {
|
||||
isLoading$ = this.claimService.isLoading$;
|
||||
claims$ = this.claimService.claims$;
|
||||
hasMore$ = this.claimService.hasMore$;
|
||||
|
||||
constructor(private claimService: ClaimsService) {}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.search({ statuses: [ClaimStatus.pending] });
|
||||
}
|
||||
|
||||
search(searchFormValue: SearchFormValue) {
|
||||
this.claimService.search(searchFormValue);
|
||||
}
|
||||
|
||||
fetchMore() {
|
||||
this.claimService.fetchMore();
|
||||
}
|
||||
}
|
@ -1,53 +0,0 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { MatSnackBar } from '@angular/material';
|
||||
import { Observable } from 'rxjs';
|
||||
import { catchError, map, shareReplay } from 'rxjs/operators';
|
||||
import { FetchResult, PartialFetcher } from '@rbkmoney/partial-fetcher';
|
||||
|
||||
import { ClaimManagementService } from '../../thrift/claim-management.service';
|
||||
import { SearchFormValue } from './search-form/search-form-value';
|
||||
import { booleanDebounceTime } from '../../shared/operators';
|
||||
import { convertFormValueToParams } from './convert-form-value-to-params';
|
||||
import { Claim } from '../../gen-damsel/claim_management';
|
||||
|
||||
@Injectable()
|
||||
export class ClaimsService extends PartialFetcher<Claim, SearchFormValue> {
|
||||
private readonly searchLimit = 20;
|
||||
|
||||
claims$: Observable<Claim> = this.searchResult$.pipe(
|
||||
catchError(() => {
|
||||
this.snackBar.open('An error occurred while processing your search', 'OK');
|
||||
return [];
|
||||
})
|
||||
);
|
||||
|
||||
isLoading$: Observable<boolean> = this.doAction$.pipe(
|
||||
booleanDebounceTime(),
|
||||
shareReplay(1)
|
||||
);
|
||||
|
||||
constructor(
|
||||
private claimManagementService: ClaimManagementService,
|
||||
private snackBar: MatSnackBar
|
||||
) {
|
||||
super();
|
||||
}
|
||||
|
||||
protected fetch(
|
||||
searchFormValue: SearchFormValue,
|
||||
continuationToken: string
|
||||
): Observable<FetchResult<Claim>> {
|
||||
return this.claimManagementService
|
||||
.searchClaims({
|
||||
...convertFormValueToParams(searchFormValue),
|
||||
continuation_token: continuationToken,
|
||||
limit: this.searchLimit
|
||||
})
|
||||
.pipe(
|
||||
map(r => ({
|
||||
result: r.result,
|
||||
continuationToken: r.continuation_token
|
||||
}))
|
||||
);
|
||||
}
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
import { SearchFormValue } from './search-form/search-form-value';
|
||||
|
||||
export const convertFormValueToParams = (params: SearchFormValue) => {
|
||||
const result = {};
|
||||
for (const k in params) {
|
||||
if (params.hasOwnProperty(k)) {
|
||||
if (k === 'statuses') {
|
||||
result[k] = (params[k] as string[]).reduce((acc, cv) => [...acc, { [cv]: {} }], []);
|
||||
} else {
|
||||
const v = params[k].trim();
|
||||
if (v === '') {
|
||||
break;
|
||||
}
|
||||
result[k] = v;
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
};
|
@ -1 +0,0 @@
|
||||
export * from './claims.module';
|
@ -1,7 +0,0 @@
|
||||
import * as domain from '../../../gen-damsel/domain';
|
||||
import { ClaimStatus } from '../../../papi/model/claim-statuses';
|
||||
|
||||
export interface SearchFormValue {
|
||||
party_id?: domain.PartyID;
|
||||
statuses?: ClaimStatus[];
|
||||
}
|
@ -1,24 +0,0 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { FormBuilder, FormGroup } from '@angular/forms';
|
||||
import values from 'lodash-es/values';
|
||||
import { ClaimStatus } from '../../../papi/model/claim-statuses';
|
||||
|
||||
@Injectable()
|
||||
export class SearchFormService {
|
||||
form: FormGroup;
|
||||
|
||||
claimStatuses: string[];
|
||||
|
||||
constructor(private fb: FormBuilder) {
|
||||
this.form = this.prepareForm();
|
||||
this.claimStatuses = values(ClaimStatus);
|
||||
this.form.patchValue({ statuses: [ClaimStatus.pending] });
|
||||
}
|
||||
|
||||
private prepareForm(): FormGroup {
|
||||
return this.fb.group({
|
||||
statuses: '',
|
||||
party_id: ''
|
||||
});
|
||||
}
|
||||
}
|
@ -1,13 +1,14 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { RouterModule } from '@angular/router';
|
||||
|
||||
import { ClaimsComponent } from './claims.component';
|
||||
import { AppAuthGuardService } from '../../app-auth-guard.service';
|
||||
import { AppAuthGuardService } from '../app-auth-guard.service';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
RouterModule.forChild([
|
||||
{
|
||||
path: '',
|
||||
path: 'claims',
|
||||
component: ClaimsComponent,
|
||||
canActivate: [AppAuthGuardService],
|
||||
data: {
|
@ -1,15 +1,15 @@
|
||||
<table mat-table [dataSource]="claims">
|
||||
<ng-container matColumnDef="partyID">
|
||||
<th mat-header-cell *matHeaderCellDef>Party ID</th>
|
||||
<td mat-cell *matCellDef="let claim">{{ claim.party_id }}</td>
|
||||
<td mat-cell *matCellDef="let claim">{{ claim.partyId }}</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="claimID">
|
||||
<th fxHide.sm fxHide.xs mat-header-cell *matHeaderCellDef>Claim ID</th>
|
||||
<td fxHide.sm fxHide.xs mat-cell *matCellDef="let claim">{{ claim.id }}</td>
|
||||
<td fxHide.sm fxHide.xs mat-cell *matCellDef="let claim">{{ claim.claimId }}</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="status">
|
||||
<th mat-header-cell *matHeaderCellDef>Status</th>
|
||||
<td mat-cell *matCellDef="let claim">{{ getClaimStatus(claim.status) }}</td>
|
||||
<td mat-cell *matCellDef="let claim">{{ claim.status }}</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="revision">
|
||||
<th fxHide.sm fxHide.xs mat-header-cell *matHeaderCellDef>Revision</th>
|
||||
@ -18,19 +18,19 @@
|
||||
<ng-container matColumnDef="createdAt">
|
||||
<th fxHide.xs mat-header-cell *matHeaderCellDef>Created at</th>
|
||||
<td fxHide.xs mat-cell *matCellDef="let claim">
|
||||
{{ claim.created_at | date: 'dd.MM.yyyy HH:mm:ss' }}
|
||||
{{ claim.createdAt | date: 'dd.MM.yyyy HH:mm:ss' }}
|
||||
</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="updatedAt">
|
||||
<th fxHide.sm fxHide.xs mat-header-cell *matHeaderCellDef>Updated at</th>
|
||||
<td fxHide.sm fxHide.xs mat-cell *matCellDef="let claim">
|
||||
{{ claim.updated_at | date: 'dd.MM.yyyy HH:mm:ss' }}
|
||||
{{ claim.updatedAt | date: 'dd.MM.yyyy HH:mm:ss' }}
|
||||
</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="claimDetailButton">
|
||||
<th mat-header-cell *matHeaderCellDef class="action-cell"></th>
|
||||
<td mat-cell *matCellDef="let claim" class="action-cell">
|
||||
<button mat-icon-button (click)="navigateToClaim(claim.party_id, claim.id)">
|
||||
<button mat-icon-button (click)="navigateToClaim(claim)">
|
||||
<mat-icon>more_vert</mat-icon>
|
||||
</button>
|
||||
</td>
|
@ -1,8 +1,8 @@
|
||||
import { Component, Input } from '@angular/core';
|
||||
import { Router } from '@angular/router';
|
||||
|
||||
import { Claim, ClaimStatus } from '../../../gen-damsel/claim_management';
|
||||
import { extractClaimStatus } from '../../../shared/extract-claim-status';
|
||||
import { ClaimInfo } from '../../papi/model';
|
||||
import { ClaimActionType } from '../../claim/claim-action-type';
|
||||
|
||||
@Component({
|
||||
selector: 'cc-claims-table',
|
||||
@ -11,9 +11,10 @@ import { extractClaimStatus } from '../../../shared/extract-claim-status';
|
||||
})
|
||||
export class ClaimsTableComponent {
|
||||
@Input()
|
||||
claims: Claim[];
|
||||
claims: ClaimInfo[];
|
||||
|
||||
displayedColumns = [
|
||||
'partyID',
|
||||
'claimID',
|
||||
'status',
|
||||
'revision',
|
||||
@ -24,11 +25,8 @@ export class ClaimsTableComponent {
|
||||
|
||||
constructor(private router: Router) {}
|
||||
|
||||
navigateToClaim(partyID: string, claimID: number) {
|
||||
this.router.navigate([`party/${partyID}/claim/${claimID}`]);
|
||||
}
|
||||
|
||||
getClaimStatus(status: ClaimStatus) {
|
||||
return extractClaimStatus(status);
|
||||
navigateToClaim(claim: ClaimInfo) {
|
||||
const c = claim as any;
|
||||
this.router.navigate([`/claims/${c.partyId}/${ClaimActionType.edit}/${c.claimId}`]);
|
||||
}
|
||||
}
|
@ -4,7 +4,7 @@
|
||||
<mat-card-content>
|
||||
<cc-search-form (valueChanges)="search($event)"></cc-search-form>
|
||||
</mat-card-content>
|
||||
<mat-card-footer *ngIf="(isLoading$ | async)">
|
||||
<mat-card-footer *ngIf="isLoading">
|
||||
<mat-progress-bar mode="indeterminate"></mat-progress-bar>
|
||||
</mat-card-footer>
|
||||
</mat-card>
|
||||
@ -14,15 +14,5 @@
|
||||
<cc-claim-actions></cc-claim-actions>
|
||||
</mat-card-content>
|
||||
</mat-card>
|
||||
<div class="mat-elevation-z2" fxLayout="column">
|
||||
<cc-claims-table [claims]="claims$ | async"></cc-claims-table>
|
||||
<button
|
||||
mat-raised-button
|
||||
*ngIf="(hasMore$ | async)"
|
||||
(click)="fetchMore()"
|
||||
[disabled]="isLoading$ | async"
|
||||
>
|
||||
Load more...
|
||||
</button>
|
||||
</div>
|
||||
<div class="mat-elevation-z2"><cc-claims-table [claims]="claims"></cc-claims-table></div>
|
||||
</cc-card-container>
|
39
src/app/claims/claims.component.ts
Normal file
39
src/app/claims/claims.component.ts
Normal file
@ -0,0 +1,39 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { MatSnackBar } from '@angular/material';
|
||||
import { HttpErrorResponse } from '@angular/common/http';
|
||||
|
||||
import { ClaimService } from '../papi/claim.service';
|
||||
import { ClaimSearchParams } from '../papi/params';
|
||||
import { ClaimInfo } from '../papi/model';
|
||||
|
||||
@Component({
|
||||
templateUrl: 'claims.component.html',
|
||||
styleUrls: []
|
||||
})
|
||||
export class ClaimsComponent implements OnInit {
|
||||
isLoading = false;
|
||||
|
||||
claims: ClaimInfo[];
|
||||
|
||||
constructor(private claimService: ClaimService, private snackBar: MatSnackBar) {}
|
||||
|
||||
ngOnInit() {
|
||||
this.search({ claimStatus: 'pending' });
|
||||
}
|
||||
|
||||
search(params: ClaimSearchParams) {
|
||||
this.isLoading = true;
|
||||
this.claimService.getClaims(params).subscribe(
|
||||
claims => {
|
||||
this.isLoading = false;
|
||||
this.claims = claims.reverse();
|
||||
},
|
||||
(error: HttpErrorResponse) => {
|
||||
this.isLoading = false;
|
||||
this.snackBar.open(`${error.status}: ${error.message}`, 'OK', {
|
||||
duration: 1500
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
@ -18,20 +18,18 @@ import { ReactiveFormsModule } from '@angular/forms';
|
||||
import { CdkTableModule } from '@angular/cdk/table';
|
||||
|
||||
import { ClaimsComponent } from './claims.component';
|
||||
import { PapiModule } from '../../papi/papi.module';
|
||||
import { ClaimsRoutingModule } from './claims-routing.module';
|
||||
import { PapiModule } from '../papi/papi.module';
|
||||
import { SearchFormComponent } from './search-form/search-form.component';
|
||||
import { ClaimsTableComponent } from './claims-table/claims-table.component';
|
||||
import { ClaimActionsComponent } from './claim-actions/claim-actions.component';
|
||||
import { CreateClaimComponent } from './create-claim/create-claim.component';
|
||||
import { SharedModule } from '../../shared/shared.module';
|
||||
import { ClaimsService } from './claims.service';
|
||||
import { ClaimManagementService } from '../../thrift/claim-management.service';
|
||||
import { ClaimsRoutingModule } from './claims-routing.module';
|
||||
import { SharedModule } from '../shared/shared.module';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
ClaimsRoutingModule,
|
||||
CommonModule,
|
||||
ClaimsRoutingModule,
|
||||
FlexLayoutModule,
|
||||
PapiModule,
|
||||
ReactiveFormsModule,
|
||||
@ -56,7 +54,6 @@ import { ClaimsRoutingModule } from './claims-routing.module';
|
||||
ClaimActionsComponent,
|
||||
CreateClaimComponent
|
||||
],
|
||||
entryComponents: [CreateClaimComponent],
|
||||
providers: [ClaimsService, ClaimManagementService]
|
||||
entryComponents: [CreateClaimComponent]
|
||||
})
|
||||
export class ClaimsModule {}
|
@ -3,7 +3,7 @@ import { FormBuilder, FormGroup, Validators } from '@angular/forms';
|
||||
import { MatDialogRef } from '@angular/material';
|
||||
import { Router } from '@angular/router';
|
||||
|
||||
import { ClaimActionType } from '../../../claim/claim-action-type';
|
||||
import { ClaimActionType } from '../../claim/claim-action-type';
|
||||
|
||||
@Component({
|
||||
templateUrl: 'create-claim.component.html'
|
@ -1,12 +1,13 @@
|
||||
<form fxLayout="row" fxLayout.xs="column" fxLayoutGap="20px" [formGroup]="form">
|
||||
<mat-form-field fxFlex="15" fxFlex.sm="30">
|
||||
<mat-select placeholder="Claim status" formControlName="statuses" multiple>
|
||||
<mat-select placeholder="Claim status" formControlName="claimStatus">
|
||||
<mat-option [value]="null">any</mat-option>
|
||||
<mat-option *ngFor="let status of claimStatuses" [value]="status">{{
|
||||
status
|
||||
}}</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
<mat-form-field fxFlex="30" fxFlex.sm="70">
|
||||
<input matInput placeholder="Party ID" formControlName="party_id" />
|
||||
<input matInput placeholder="Party ID" formControlName="partyId" />
|
||||
</mat-form-field>
|
||||
</form>
|
@ -2,8 +2,8 @@ import { Component, EventEmitter, OnInit, Output } from '@angular/core';
|
||||
import { FormGroup } from '@angular/forms';
|
||||
|
||||
import { SearchFormService } from './search-form.service';
|
||||
import { ClaimSearchParams } from '../../papi/params';
|
||||
import { debounceTime } from 'rxjs/internal/operators';
|
||||
import { SearchFormValue } from './search-form-value';
|
||||
|
||||
@Component({
|
||||
selector: 'cc-search-form',
|
||||
@ -12,7 +12,7 @@ import { SearchFormValue } from './search-form-value';
|
||||
})
|
||||
export class SearchFormComponent implements OnInit {
|
||||
@Output()
|
||||
valueChanges: EventEmitter<SearchFormValue> = new EventEmitter();
|
||||
valueChanges: EventEmitter<ClaimSearchParams> = new EventEmitter();
|
||||
|
||||
form: FormGroup;
|
||||
|
||||
@ -21,11 +21,11 @@ export class SearchFormComponent implements OnInit {
|
||||
constructor(private searchFormService: SearchFormService) {}
|
||||
|
||||
ngOnInit() {
|
||||
const { form, claimStatuses } = this.searchFormService;
|
||||
const { claimStatuses, form, formValueToSearchParams } = this.searchFormService;
|
||||
this.claimStatuses = claimStatuses;
|
||||
this.form = form;
|
||||
this.form.valueChanges.pipe(debounceTime(300)).subscribe(value => {
|
||||
this.valueChanges.emit(value);
|
||||
});
|
||||
this.form.valueChanges
|
||||
.pipe(debounceTime(300))
|
||||
.subscribe(value => this.valueChanges.emit(formValueToSearchParams(value)));
|
||||
}
|
||||
}
|
39
src/app/claims/search-form/search-form.service.ts
Normal file
39
src/app/claims/search-form/search-form.service.ts
Normal file
@ -0,0 +1,39 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { FormBuilder, FormGroup } from '@angular/forms';
|
||||
import values from 'lodash-es/values';
|
||||
import mapValues from 'lodash-es/mapValues';
|
||||
import isString from 'lodash-es/isString';
|
||||
|
||||
import { ClaimStatus } from '../../papi/model/claim-statuses';
|
||||
import { ClaimSearchParams } from '../../papi/params';
|
||||
|
||||
@Injectable()
|
||||
export class SearchFormService {
|
||||
form: FormGroup;
|
||||
|
||||
claimStatuses: string[];
|
||||
|
||||
constructor(private fb: FormBuilder) {
|
||||
this.form = this.prepareForm();
|
||||
this.claimStatuses = values(ClaimStatus);
|
||||
}
|
||||
|
||||
formValueToSearchParams(formValue): ClaimSearchParams {
|
||||
return mapValues(formValue, value => {
|
||||
let result = value;
|
||||
if (value === '') {
|
||||
result = null;
|
||||
} else if (isString(value)) {
|
||||
result = value.trim();
|
||||
}
|
||||
return result;
|
||||
});
|
||||
}
|
||||
|
||||
private prepareForm(): FormGroup {
|
||||
return this.fb.group({
|
||||
claimStatus: 'pending',
|
||||
partyId: ''
|
||||
});
|
||||
}
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Subject } from 'rxjs';
|
||||
|
||||
import { DomainPair } from './domain-group';
|
||||
import { DomainPair } from './domain-group/domain-group';
|
||||
|
||||
@Injectable()
|
||||
export class DomainDetailsService {
|
||||
|
@ -2,12 +2,12 @@ import { Component, OnInit, Input, OnChanges, SimpleChanges, ViewChild } from '@
|
||||
import { MatTableDataSource, MatPaginator, MatSort } from '@angular/material';
|
||||
|
||||
import { DomainGroup } from '../domain-group';
|
||||
import { DomainDetailsService } from '../../domain-details.service';
|
||||
import { DomainDetailsService } from '../../../domain-info/domain-details.service';
|
||||
import { toTableGroup, toDataSource } from './table-group';
|
||||
import { sortData } from './sort-table-data';
|
||||
import { filterPredicate } from './filter-predicate';
|
||||
import { TableDataSource, TableGroup } from './model';
|
||||
import { DetailsContainerService } from '../../details-container.service';
|
||||
import { DetailsContainerService } from '../../../domain-info/details-container.service';
|
||||
|
||||
@Component({
|
||||
selector: 'cc-group-table',
|
||||
|
@ -1,10 +1,11 @@
|
||||
import { parse } from '../../jsonc/json-parser';
|
||||
import {
|
||||
CodeLensProvider,
|
||||
ITextModel,
|
||||
CancellationToken,
|
||||
ICodeLensSymbol,
|
||||
ProviderResult
|
||||
} from '../../monaco-editor';
|
||||
} from '../../monaco-editor/model';
|
||||
|
||||
export class DomainObjCodeLensProvider implements CodeLensProvider {
|
||||
get language() {
|
||||
|
@ -3,7 +3,7 @@ import { MatSnackBar, MatDialog } from '@angular/material';
|
||||
import { Router } from '@angular/router';
|
||||
import { Subscription } from 'rxjs';
|
||||
|
||||
import { MonacoFile, CodeLensProvider, CompletionProvider } from '../../monaco-editor';
|
||||
import { MonacoFile, CodeLensProvider, CompletionProvider } from '../../monaco-editor/model';
|
||||
import { DomainObjModificationService } from './domain-obj-modification.service';
|
||||
import { DomainObjCodeLensProvider } from './domain-obj-code-lens-provider';
|
||||
import { DomainObjCompletionProvider } from './domain-obj-completion-provider';
|
||||
|
@ -11,7 +11,7 @@ import { MatIconModule } from '@angular/material/icon';
|
||||
import { RouterModule } from '@angular/router';
|
||||
|
||||
import { DomainObjModificationComponent } from './domain-obj-modification.component';
|
||||
import { MonacoEditorModule } from '../../monaco-editor';
|
||||
import { MonacoEditorModule } from '../../monaco-editor/monaco-editor.module';
|
||||
import { SharedModule } from '../../shared/shared.module';
|
||||
import { ResetConfirmDialogComponent } from './reset-confirm-dialog/reset-confirm-dialog.component';
|
||||
|
||||
|
@ -3,7 +3,7 @@ import { Router } from '@angular/router';
|
||||
import { MatCheckboxChange, MatSnackBar } from '@angular/material';
|
||||
import { Subscription } from 'rxjs';
|
||||
|
||||
import { MonacoFile, IDiffEditorOptions } from '../../monaco-editor';
|
||||
import { MonacoFile, IDiffEditorOptions } from '../../monaco-editor/model';
|
||||
import { toMonacoFile } from '../utils';
|
||||
import { DomainModificationModel } from '../domain-modification-model';
|
||||
import { DomainObjReviewService } from './domain-obj-review.service';
|
||||
|
@ -10,7 +10,7 @@ import {
|
||||
} from '@angular/material';
|
||||
|
||||
import { DomainObjReviewComponent } from './domain-obj-review.component';
|
||||
import { MonacoEditorModule } from '../../monaco-editor';
|
||||
import { MonacoEditorModule } from '../../monaco-editor/monaco-editor.module';
|
||||
import { SharedModule } from '../../shared/shared.module';
|
||||
|
||||
@NgModule({
|
||||
|
@ -4,7 +4,7 @@ import { DomainRoutingModule } from './domain-routing.module';
|
||||
import { DomainService } from './domain.service';
|
||||
import { MetadataService } from './metadata.service';
|
||||
import { DomainObjModificationModule } from './domain-obj-modification';
|
||||
import { DomainInfoModule } from './domain-info';
|
||||
import { DomainInfoModule } from './domain-info/domain-info.module';
|
||||
import { DamselMetaModule } from '../damsel-meta/damsel-meta.module';
|
||||
import { DomainObjReviewModule } from './domain-obj-review';
|
||||
import { DomainReviewService } from './domain-review.service';
|
||||
|
@ -1,11 +1,11 @@
|
||||
import { Injectable, NgZone } from '@angular/core';
|
||||
import { Observable } from 'rxjs';
|
||||
import { KeycloakService } from 'keycloak-angular';
|
||||
|
||||
import { DepositParams } from './gen-model/fistful_admin';
|
||||
import { DepositParams as DepositParamsObject } from './gen-nodejs/fistful_admin_types';
|
||||
import { ThriftService } from '../thrift';
|
||||
import * as FistfulAdmin from './gen-nodejs/FistfulAdmin';
|
||||
import { KeycloakService } from 'keycloak-angular';
|
||||
|
||||
@Injectable()
|
||||
export class FistfulAdminService extends ThriftService {
|
||||
|
@ -1,11 +1,11 @@
|
||||
import { Injectable, NgZone } from '@angular/core';
|
||||
import { Observable } from 'rxjs';
|
||||
import { KeycloakService } from 'keycloak-angular';
|
||||
|
||||
import { ThriftService } from '../thrift';
|
||||
import { RepairScenario, SessionID } from './gen-model/withdrawal_session';
|
||||
import { RepairScenario as RepairScenarioObject } from './gen-nodejs/withdrawal_session_types';
|
||||
import * as Repairer from './gen-nodejs/Repairer';
|
||||
import { KeycloakService } from 'keycloak-angular';
|
||||
|
||||
@Injectable()
|
||||
export class RepairerService extends ThriftService {
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { Injectable, NgZone } from '@angular/core';
|
||||
import { Observable } from 'rxjs';
|
||||
import { KeycloakService } from 'keycloak-angular';
|
||||
|
||||
import * as Automaton from './gen-nodejs/Automaton';
|
||||
import {
|
||||
@ -9,7 +10,6 @@ import {
|
||||
import { ThriftService } from '../thrift';
|
||||
import { Namespace } from './gen-model/base';
|
||||
import { Reference, MachineDescriptor, Machine } from './gen-model/state_processing';
|
||||
import { KeycloakService } from 'keycloak-angular';
|
||||
|
||||
@Injectable()
|
||||
export class AutomatonService extends ThriftService {
|
||||
|
@ -6,8 +6,7 @@ import { map } from 'rxjs/operators';
|
||||
import { ClaimCreated, ClaimInfo, PartyModificationUnit } from './model';
|
||||
import { ConfigService } from '../core/config.service';
|
||||
import { decode, encode } from '../shared/java-thrift-formatter';
|
||||
import { ClaimAcceptParams, ClaimDenyParams } from './params';
|
||||
import { ClaimSearchQuery } from '../gen-damsel/claim_management';
|
||||
import { ClaimAcceptParams, ClaimDenyParams, ClaimSearchParams } from './params';
|
||||
|
||||
@Injectable()
|
||||
export class ClaimService {
|
||||
@ -17,7 +16,7 @@ export class ClaimService {
|
||||
this.papiEndpoint = configService.config.papiEndpoint;
|
||||
}
|
||||
|
||||
getClaims(params: ClaimSearchQuery): Observable<ClaimInfo[]> {
|
||||
getClaims(params: ClaimSearchParams): Observable<ClaimInfo[]> {
|
||||
return this.http.post<ClaimInfo[]>(`${this.papiEndpoint}/walk/claim/search`, params);
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,5 @@ export enum ClaimStatus {
|
||||
accepted = 'accepted',
|
||||
denied = 'denied',
|
||||
revoked = 'revoked',
|
||||
pending = 'pending',
|
||||
review = 'review',
|
||||
pending_acceptance = 'pending_acceptance'
|
||||
pending = 'pending'
|
||||
}
|
||||
|
@ -1,17 +0,0 @@
|
||||
export enum StatusColor {
|
||||
neutral = 'neutral',
|
||||
success = 'success',
|
||||
pending = 'pending',
|
||||
warn = 'warn'
|
||||
}
|
||||
|
||||
export enum PaletteColor {
|
||||
primary = 'primary',
|
||||
accent = 'accent',
|
||||
warn = 'warn'
|
||||
}
|
||||
|
||||
export type Status = keyof typeof StatusColor;
|
||||
export type Palette = keyof typeof PaletteColor;
|
||||
|
||||
export const slateblue400 = '#695BFF';
|
@ -1,2 +0,0 @@
|
||||
export * from './timeline.module';
|
||||
export * from './timeline.component';
|
@ -1 +0,0 @@
|
||||
export * from './timeline-item.component';
|
@ -1 +0,0 @@
|
||||
export * from './timeline-item-badge.component';
|
@ -1,10 +0,0 @@
|
||||
<div
|
||||
[ngClass]="{
|
||||
'cc-timeline-item-badge': true,
|
||||
'cc-timeline-item-badge-success': color === 'success',
|
||||
'cc-timeline-item-badge-warn': color === 'warn',
|
||||
'cc-timeline-item-badge-pending': color === 'pending'
|
||||
}"
|
||||
>
|
||||
<ng-content></ng-content>
|
||||
</div>
|
@ -1,31 +0,0 @@
|
||||
@import '../timeline-item.scss';
|
||||
@import '../../../../styles/light';
|
||||
|
||||
$size: 36px;
|
||||
$line-size: 2px;
|
||||
|
||||
$neutral: map-get($theme, neutral);
|
||||
$line-color: mat-color($neutral, 200);
|
||||
.cc-timeline-item-badge {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
display: flex;
|
||||
height: $size;
|
||||
width: $size;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
border-radius: 50%;
|
||||
z-index: 10;
|
||||
|
||||
::ng-deep > *,
|
||||
::ng-deep > * mat-icon {
|
||||
height: $icons-size;
|
||||
width: $icons-size;
|
||||
font-size: $icons-size;
|
||||
}
|
||||
}
|
||||
|
||||
.cc-timeline-item-badge {
|
||||
background-color: $line-color;
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
import { Component, Input } from '@angular/core';
|
||||
import { StatusColor } from '../../../../color';
|
||||
|
||||
@Component({
|
||||
selector: 'cc-timeline-item-badge',
|
||||
templateUrl: 'timeline-item-badge.component.html',
|
||||
styleUrls: ['timeline-item-badge.component.scss']
|
||||
})
|
||||
export class TimelineItemBadgeComponent {
|
||||
@Input() color: StatusColor;
|
||||
}
|
@ -1 +0,0 @@
|
||||
export * from './timeline-item-content.component';
|
@ -1,5 +0,0 @@
|
||||
@import '../timeline-item.scss';
|
||||
|
||||
.cc-timeline-item-content {
|
||||
padding-top: $content-padding;
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
import { Component, ViewEncapsulation, HostBinding } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'cc-timeline-item-content, [cc-timeline-item-content]',
|
||||
template: '<ng-content></ng-content>',
|
||||
styleUrls: ['timeline-item-content.component.scss'],
|
||||
encapsulation: ViewEncapsulation.None
|
||||
})
|
||||
export class TimelineItemContentComponent {
|
||||
@HostBinding('class.cc-timeline-item-content') rootClass = true;
|
||||
}
|
@ -1 +0,0 @@
|
||||
export * from './timeline-item-title.component';
|
@ -1,3 +0,0 @@
|
||||
<div class="cc-timeline-item-title">
|
||||
<div><ng-content></ng-content></div>
|
||||
</div>
|
@ -1,7 +0,0 @@
|
||||
@import '../timeline-item.scss';
|
||||
|
||||
.cc-timeline-item-title {
|
||||
min-height: $size;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
@ -1,8 +0,0 @@
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'cc-timeline-item-title',
|
||||
templateUrl: 'timeline-item-title.component.html',
|
||||
styleUrls: ['timeline-item-title.component.scss']
|
||||
})
|
||||
export class TimelineItemTitleComponent {}
|
@ -1 +0,0 @@
|
||||
<div class="cc-timeline-item"><ng-content></ng-content></div>
|
@ -1,7 +0,0 @@
|
||||
@import './timeline-item.scss';
|
||||
|
||||
.cc-timeline-item {
|
||||
padding-bottom: 20px;
|
||||
padding-left: $size + $content-padding;
|
||||
position: relative;
|
||||
}
|
@ -1,8 +0,0 @@
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'cc-timeline-item',
|
||||
templateUrl: 'timeline-item.component.html',
|
||||
styleUrls: ['timeline-item.component.scss']
|
||||
})
|
||||
export class TimelineItemComponent {}
|
@ -1,4 +0,0 @@
|
||||
$size: 36px;
|
||||
$icons-size: 18px;
|
||||
$line-size: 2px;
|
||||
$content-padding: 10px;
|
@ -1 +0,0 @@
|
||||
<div fxLayout="column" class="cc-timeline"><ng-content></ng-content></div>
|
@ -1,24 +0,0 @@
|
||||
@import '../../styles/light';
|
||||
|
||||
$size: 36px;
|
||||
$line-size: 2px;
|
||||
|
||||
$neutral: map-get($theme, neutral);
|
||||
$line-color: mat-color($neutral, 200);
|
||||
|
||||
.cc-timeline {
|
||||
position: relative;
|
||||
border-bottom: $line-size solid;
|
||||
border-bottom-color: $line-color;
|
||||
font-family: Roboto, "Helvetica Neue", sans-serif;
|
||||
|
||||
&::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
width: $line-size;
|
||||
left: $size / 2 - $line-size / 2;
|
||||
background-color: $line-color;
|
||||
}
|
||||
}
|
@ -1,8 +0,0 @@
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'cc-timeline',
|
||||
templateUrl: 'timeline.component.html',
|
||||
styleUrls: ['timeline.component.scss']
|
||||
})
|
||||
export class TimelineComponent {}
|
@ -1,24 +0,0 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { FlexLayoutModule } from '@angular/flex-layout';
|
||||
import { CommonModule } from '@angular/common';
|
||||
|
||||
import { TimelineComponent } from './timeline.component';
|
||||
import { TimelineItemComponent } from './timeline-item';
|
||||
import { TimelineItemTitleComponent } from './timeline-item/timeline-item-title';
|
||||
import { TimelineItemBadgeComponent } from './timeline-item/timeline-item-badge';
|
||||
import { TimelineItemContentComponent } from './timeline-item/timeline-item-content';
|
||||
|
||||
const EXPORTED_DECLARATIONS = [
|
||||
TimelineComponent,
|
||||
TimelineItemComponent,
|
||||
TimelineItemTitleComponent,
|
||||
TimelineItemBadgeComponent,
|
||||
TimelineItemContentComponent
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
imports: [FlexLayoutModule, CommonModule],
|
||||
declarations: EXPORTED_DECLARATIONS,
|
||||
exports: EXPORTED_DECLARATIONS
|
||||
})
|
||||
export class TimelineModule {}
|
@ -1,15 +0,0 @@
|
||||
import { ClaimStatus as UnionClaimStatus } from '../gen-damsel/claim_management';
|
||||
import { ClaimStatus } from '../papi/model/claim-statuses';
|
||||
import { getUnionKey } from './get-union-key';
|
||||
|
||||
export const claimStatusByUnionClaimStatus: { [name in keyof UnionClaimStatus]-?: ClaimStatus } = {
|
||||
accepted: ClaimStatus.accepted,
|
||||
denied: ClaimStatus.denied,
|
||||
revoked: ClaimStatus.revoked,
|
||||
pending: ClaimStatus.pending,
|
||||
review: ClaimStatus.review,
|
||||
pending_acceptance: ClaimStatus.pending_acceptance
|
||||
};
|
||||
|
||||
export const extractClaimStatus = (status: UnionClaimStatus): ClaimStatus =>
|
||||
claimStatusByUnionClaimStatus[getUnionKey(status) as keyof UnionClaimStatus];
|
@ -1 +0,0 @@
|
||||
export const getUnionKey = (union: any) => Object.entries(union).find(([, v]) => !!v)[0];
|
@ -1,11 +0,0 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
|
||||
import { HumanizedDurationPipe } from './humanized-duration.pipe';
|
||||
import { HumanizeDurationService } from './humanize-duration.service';
|
||||
|
||||
@NgModule({
|
||||
declarations: [HumanizedDurationPipe],
|
||||
providers: [HumanizeDurationService],
|
||||
exports: [HumanizedDurationPipe]
|
||||
})
|
||||
export class HumanizeDurationModule {}
|
@ -1,70 +0,0 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import * as humanizeDuration from 'humanize-duration';
|
||||
import * as moment from 'moment';
|
||||
|
||||
export type Value = number | string | moment.Moment | Date;
|
||||
|
||||
export interface HumanizeConfig extends humanizeDuration.HumanizerOptions {
|
||||
isShort?: boolean;
|
||||
hasAgoEnding?: boolean;
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
export class HumanizeDurationService {
|
||||
static HOUR_MS = 3600000;
|
||||
static MIN_HUMANIZE_DURATION_UPDATE_MS = 1000;
|
||||
static MOMENT_HUMANIZE_ALLOWED_DELAY_BETWEEN_UPDATES_FOR_MINUTE_UPDATES_MS = 20000;
|
||||
static MOMENT_HUMANIZE_ALLOWED_DELAY_BETWEEN_UPDATES_FOR_HOURLY_AND_LONGER_UPDATES_MS = 600000;
|
||||
static LESS_THAN_FEW_SECONDS = 3000;
|
||||
|
||||
private get duration() {
|
||||
return humanizeDuration.humanizer({
|
||||
language: 'en',
|
||||
round: true,
|
||||
delimiter: ' '
|
||||
});
|
||||
}
|
||||
|
||||
get shortEnglishHumanizer(): humanizeDuration.HumanizerOptions {
|
||||
return {
|
||||
language: 'short'
|
||||
};
|
||||
}
|
||||
|
||||
getDiffMs(value: Value): number {
|
||||
return Math.abs(this.isDiff(value) ? value : moment().diff(moment(value)));
|
||||
}
|
||||
|
||||
getDuration(value: Value, config: HumanizeConfig = {}): string {
|
||||
const diffMs = this.getDiffMs(value);
|
||||
let duration = this.duration(diffMs, config);
|
||||
if (isNaN(diffMs)) {
|
||||
return null;
|
||||
} else if (diffMs < HumanizeDurationService.LESS_THAN_FEW_SECONDS) {
|
||||
return 'just now';
|
||||
} else if (config.isShort) {
|
||||
duration = this.duration(diffMs, { ...config, ...this.shortEnglishHumanizer });
|
||||
} else if (config.largest === 1) {
|
||||
duration = moment.duration(diffMs).humanize();
|
||||
}
|
||||
return config.hasAgoEnding ? `${duration} ago` : duration;
|
||||
}
|
||||
|
||||
getOptimalUpdateInterval(value: Value, { largest }: HumanizeConfig): number {
|
||||
const diffMs = this.getDiffMs(value);
|
||||
if (diffMs < HumanizeDurationService.LESS_THAN_FEW_SECONDS) {
|
||||
return HumanizeDurationService.MIN_HUMANIZE_DURATION_UPDATE_MS;
|
||||
}
|
||||
if (largest === 1) {
|
||||
if (diffMs < HumanizeDurationService.HOUR_MS) {
|
||||
return HumanizeDurationService.MOMENT_HUMANIZE_ALLOWED_DELAY_BETWEEN_UPDATES_FOR_MINUTE_UPDATES_MS;
|
||||
}
|
||||
return HumanizeDurationService.MOMENT_HUMANIZE_ALLOWED_DELAY_BETWEEN_UPDATES_FOR_HOURLY_AND_LONGER_UPDATES_MS;
|
||||
}
|
||||
return HumanizeDurationService.MIN_HUMANIZE_DURATION_UPDATE_MS;
|
||||
}
|
||||
|
||||
isDiff(value: Value): value is number {
|
||||
return typeof value === 'number';
|
||||
}
|
||||
}
|
@ -1,54 +0,0 @@
|
||||
import { Pipe, PipeTransform, ChangeDetectorRef, OnDestroy } from '@angular/core';
|
||||
import { Subscription, interval } from 'rxjs';
|
||||
import { HumanizerOptions } from 'humanize-duration';
|
||||
|
||||
import { HumanizeConfig, HumanizeDurationService, Value } from './humanize-duration.service';
|
||||
|
||||
export interface HumanizeDurationConfig extends HumanizeConfig {
|
||||
interval?: number;
|
||||
}
|
||||
|
||||
@Pipe({ name: 'humanizedDuration', pure: false })
|
||||
export class HumanizedDurationPipe implements OnDestroy, PipeTransform {
|
||||
private latestValue: string;
|
||||
private subscription: Subscription;
|
||||
private inputValue: Value;
|
||||
|
||||
constructor(
|
||||
private humanizeDurationService: HumanizeDurationService,
|
||||
private ref: ChangeDetectorRef
|
||||
) {}
|
||||
|
||||
transform(value: Value, { interval: inpIntervalMs, ...config }: HumanizeDurationConfig = {}) {
|
||||
if (value !== this.inputValue) {
|
||||
this.inputValue = value;
|
||||
this.latestValue = this.humanizeDurationService.getDuration(value, config);
|
||||
this.dispose();
|
||||
if (!this.humanizeDurationService.isDiff(value)) {
|
||||
this.subscription = interval(
|
||||
inpIntervalMs ||
|
||||
this.humanizeDurationService.getOptimalUpdateInterval(value, config)
|
||||
).subscribe(() => this.updateValue(value, config));
|
||||
}
|
||||
}
|
||||
return this.latestValue;
|
||||
}
|
||||
|
||||
ngOnDestroy(): void {
|
||||
this.dispose();
|
||||
}
|
||||
|
||||
private dispose(): void {
|
||||
if (this.subscription) {
|
||||
this.subscription.unsubscribe();
|
||||
}
|
||||
}
|
||||
|
||||
private updateValue(value: Value, config: HumanizerOptions): void {
|
||||
const duration = this.humanizeDurationService.getDuration(value, config);
|
||||
if (duration !== this.latestValue) {
|
||||
this.ref.markForCheck();
|
||||
this.latestValue = duration;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,2 +0,0 @@
|
||||
export * from './humanize-duration.module';
|
||||
export * from './humanize-duration.service';
|
@ -1,11 +0,0 @@
|
||||
import { distinctUntilChanged, debounce } from 'rxjs/operators';
|
||||
import { timer, empty, Observable } from 'rxjs';
|
||||
|
||||
export const booleanDebounceTime = (timeoutMs: number = 500) => (
|
||||
s: Observable<boolean>
|
||||
): Observable<boolean> =>
|
||||
s.pipe(
|
||||
distinctUntilChanged(),
|
||||
debounce(v => (v ? timer(timeoutMs) : empty())),
|
||||
distinctUntilChanged()
|
||||
);
|
@ -1 +0,0 @@
|
||||
export * from './boolean-debounce-time';
|
@ -1,7 +0,0 @@
|
||||
@mixin fill($color) {
|
||||
color: $color;
|
||||
|
||||
* {
|
||||
fill: $color;
|
||||
}
|
||||
}
|
@ -1,6 +0,0 @@
|
||||
@import '../../../../node_modules/@angular/material/theming';
|
||||
|
||||
$theme: (
|
||||
name: 'light',
|
||||
neutral: mat-palette($mat-grey),
|
||||
);
|
@ -1 +0,0 @@
|
||||
export * from './sort-units';
|
@ -1,5 +0,0 @@
|
||||
import * as moment from 'moment';
|
||||
import { ModificationUnit } from '../../gen-damsel/claim_management';
|
||||
|
||||
export const sortUnitsByCreatedAtAsc = <T extends ModificationUnit>(units: T[]): T[] =>
|
||||
units.slice().sort(({ created_at: a }, { created_at: b }) => moment(a).diff(moment(b)));
|
@ -1,22 +0,0 @@
|
||||
import { Injectable, NgZone } from '@angular/core';
|
||||
import { Observable } from 'rxjs';
|
||||
import { KeycloakService } from 'keycloak-angular';
|
||||
|
||||
import { ThriftService } from '../thrift';
|
||||
import * as ClaimManagement from './gen-nodejs/ClaimManagement';
|
||||
import { Claim, ClaimSearchQuery, ClaimSearchResponse } from '../gen-damsel/claim_management';
|
||||
import { ClaimSearchQuery as ClaimSearchQueryType } from './gen-nodejs/claim_management_types';
|
||||
|
||||
@Injectable()
|
||||
export class ClaimManagementService extends ThriftService {
|
||||
constructor(zone: NgZone, keycloakService: KeycloakService) {
|
||||
super(zone, keycloakService, '/v1/cm', ClaimManagement);
|
||||
}
|
||||
|
||||
searchClaims = (query: ClaimSearchQuery): Observable<ClaimSearchResponse> =>
|
||||
this.toObservableAction('SearchClaims')(new ClaimSearchQueryType(query));
|
||||
|
||||
getClaim = (partyID: string, claimID: number): Observable<Claim> => {
|
||||
return this.toObservableAction('GetClaim')(partyID, claimID);
|
||||
};
|
||||
}
|
@ -1,10 +1,10 @@
|
||||
import { Injectable, NgZone } from '@angular/core';
|
||||
import { Observable } from 'rxjs';
|
||||
import { KeycloakService } from 'keycloak-angular';
|
||||
|
||||
import * as Repository from './gen-nodejs/Repository';
|
||||
import { ThriftService } from './thrift-service';
|
||||
import { Reference, Snapshot, Commit, Version, Limit } from '../gen-damsel/domain_config';
|
||||
import { KeycloakService } from 'keycloak-angular';
|
||||
|
||||
@Injectable()
|
||||
export class DomainService extends ThriftService {
|
||||
|
@ -1,11 +1,11 @@
|
||||
import { Injectable, NgZone } from '@angular/core';
|
||||
import { Observable } from 'rxjs';
|
||||
import { KeycloakService } from 'keycloak-angular';
|
||||
|
||||
import * as MerchantStatistics from './gen-nodejs/MerchantStatistics';
|
||||
import { ThriftService } from './thrift-service';
|
||||
import { StatRequest, StatResponse } from '../gen-damsel/merch_stat';
|
||||
import { StatRequest as ThriftStatRequest } from './gen-nodejs/merch_stat_types';
|
||||
import { KeycloakService } from 'keycloak-angular';
|
||||
|
||||
@Injectable()
|
||||
export class MerchantStatisticsService extends ThriftService {
|
||||
|
@ -2,7 +2,12 @@ import cloneDeep from 'lodash-es/cloneDeep';
|
||||
import last from 'lodash-es/last';
|
||||
import dropRight from 'lodash-es/dropRight';
|
||||
|
||||
import { ProviderObject, TerminalDecision, TerminalRef } from '../../gen-damsel/domain';
|
||||
import {
|
||||
ProviderObject,
|
||||
TerminalSelector,
|
||||
TerminalDecision,
|
||||
TerminalRef
|
||||
} from '../../gen-damsel/domain';
|
||||
import { toGenTerminalDecision } from '../converters';
|
||||
import { checkSelector } from './utils';
|
||||
|
||||
|
@ -1,5 +1,7 @@
|
||||
import { Injectable, NgZone } from '@angular/core';
|
||||
import { Observable, timer } from 'rxjs';
|
||||
import { share, switchMap, first } from 'rxjs/operators';
|
||||
import { KeycloakService } from 'keycloak-angular';
|
||||
|
||||
import {
|
||||
InvoicePaymentAdjustmentParams as InvoicePaymentAdjustmentParamsObject,
|
||||
@ -15,8 +17,6 @@ import {
|
||||
import { ThriftService } from './thrift-service';
|
||||
import * as Invoicing from './gen-nodejs/Invoicing';
|
||||
import { InvoiceID } from '../gen-damsel/domain';
|
||||
import { share, switchMap, first } from 'rxjs/operators';
|
||||
import { KeycloakService } from 'keycloak-angular';
|
||||
|
||||
@Injectable()
|
||||
export class PaymentProcessingService extends ThriftService {
|
||||
|
@ -11,10 +11,9 @@ type Exception<N = string, T = {}> = {
|
||||
} & T;
|
||||
|
||||
export class ThriftService {
|
||||
protected realm = 'internal';
|
||||
|
||||
protected endpoint: string;
|
||||
protected service: any;
|
||||
protected realm = 'internal';
|
||||
|
||||
constructor(
|
||||
private zone: NgZone,
|
||||
@ -48,7 +47,7 @@ export class ThriftService {
|
||||
}).pipe(timeout(60000))) as any;
|
||||
}
|
||||
|
||||
private createClient(errorCb: Function): Observable<any> {
|
||||
private createClient(errorCb: Function) {
|
||||
return from(this.keycloakService.getToken()).pipe(
|
||||
map(token => {
|
||||
const { email, preferred_username, sub } = jwtDecode(token);
|
||||
|
@ -5,7 +5,6 @@ import { PaymentProcessingService } from './payment-processing.service';
|
||||
import { MerchantStatisticsService } from './merchant-statistics.service';
|
||||
import { DomainTypedManager } from './domain-typed-manager';
|
||||
import { DomainCacheService } from './domain-cache.service';
|
||||
import { ClaimManagementService } from './claim-management.service';
|
||||
|
||||
@NgModule({
|
||||
providers: [
|
||||
@ -13,8 +12,7 @@ import { ClaimManagementService } from './claim-management.service';
|
||||
DomainTypedManager,
|
||||
PaymentProcessingService,
|
||||
MerchantStatisticsService,
|
||||
DomainCacheService,
|
||||
ClaimManagementService
|
||||
DomainCacheService
|
||||
]
|
||||
})
|
||||
export class ThriftModule {}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user