mirror of
https://github.com/valitydev/control-center.git
synced 2024-11-06 02:25:17 +00:00
EPIC FE-954: CLAIM-MGT (#100)
* FE-954: claim management API integration * FE-964: claim details added * FE-972: timeline * Merge with epic FE-958: claim mngt (#101) (#102) * Merge with epic FE-958: claim mngt (#101) * FE-954: claim management API integration * FE-964: claim details added * FE-972: timeline * Thrift services added * fix build * clean up * FileStorage service implemented * build fix n clean up * clean up * FE-965: claim status changer (#107) * Added claim status pipe and menu (#108) * FE-976: comments (#104) * FE-976: comments implemented, keycloaktokeninfo service added. * update * clean up * build fix * Comments added. * clean up * prettier * import order * build fix * prettier * PR fixes * пеар фиксес * build fix * pr fix * prettier * FE-977: claim mngt files (#109) * conversation filter * file display * file download * file uploading * filter removed, file upload transfered to send messages line * prettier * тп-сщтеуте куьщмувб штзкщпкуыы фввув * angular-file rollback * FE-993: party mods (#110) * Add questionary (#111) * add questionary service and component * update ank service * fox ank module * fix ank get * merge with master * lgtm * build fix * prettier * packages... * package fix * Dependencies fix (#113) Co-authored-by: Ildar Galeev <KeinAsylum@gmail.com> Co-authored-by: Rinat Arsaev <krickray@gmail.com>
This commit is contained in:
parent
a252c12660
commit
9c7073e6a1
11
.gitignore
vendored
11
.gitignore
vendored
@ -37,11 +37,14 @@ testem.log
|
||||
# System Files
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
|
||||
/src/assets/meta-damsel.json
|
||||
/src/app/thrift/gen-nodejs/
|
||||
/src/app/gen-damsel/
|
||||
/src/app/machinegun/gen-*
|
||||
/src/app/fistful/gen-*
|
||||
/src/app/thrift-services/damsel/gen-*
|
||||
/src/app/thrift-services/machinegun/gen-*
|
||||
/src/app/thrift-services/fistful/gen-*
|
||||
/src/app/thrift-services/messages/gen-*
|
||||
/src/app/thrift-services/ank/gen-*
|
||||
/src/app/thrift-services/file-storage/gen-*
|
||||
|
||||
# Sonar
|
||||
.scannerwork
|
||||
|
34
Makefile
34
Makefile
@ -41,7 +41,7 @@ submodules: $(SUBTARGETS)
|
||||
init:
|
||||
npm install
|
||||
|
||||
compile: compile-damsel compile-machinegun compile-fistful
|
||||
compile: compile-damsel compile-machinegun compile-fistful compile-messages compile-file-storage compile-ank
|
||||
|
||||
build: check lint compile
|
||||
npm run build
|
||||
@ -49,12 +49,12 @@ build: check lint compile
|
||||
clean-compile: clean compile
|
||||
|
||||
clean:
|
||||
rm -rf dist src/app/thrift/gen-* src/assets/meta-damsel.json src/app/gen-damsel src/app/machinegun/gen-* src/app/fistful/gen-*
|
||||
rm -rf dist src/app/thrift/gen-* src/assets/meta-damsel.json src/app/gen-model src/app/machinegun/gen-* src/app/fistful/gen-* src/app/messages/gen-* src/app/file-storage/gen-* src/app/ank/gen-*
|
||||
|
||||
compile-damsel: damsel-client damsel-model damsel-meta
|
||||
|
||||
damsel-client:
|
||||
@$(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;)
|
||||
@$(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-services/damsel ./node_modules/damsel/proto/$(file).thrift;)
|
||||
|
||||
damsel-meta:
|
||||
npm run damsel-meta
|
||||
@ -65,7 +65,7 @@ damsel-model:
|
||||
compile-machinegun: machinegun-model machinegun-client
|
||||
|
||||
machinegun-client:
|
||||
@$(foreach file,state_processing,echo $(file); thrift -r -gen js:node,runtime_package=woody_js/dist/thrift -o ./src/app/machinegun ./node_modules/machinegun_proto/proto/$(file).thrift;)
|
||||
@$(foreach file,state_processing,echo $(file); thrift -r -gen js:node,runtime_package=woody_js/dist/thrift -o ./src/app/thrift-services/machinegun ./node_modules/machinegun_proto/proto/$(file).thrift;)
|
||||
|
||||
machinegun-model:
|
||||
npm run machinegun-model
|
||||
@ -73,11 +73,35 @@ machinegun-model:
|
||||
compile-fistful: fistful-model fistful-client
|
||||
|
||||
fistful-client:
|
||||
@$(foreach file,withdrawal_session fistful_admin fistful_stat,echo $(file); thrift -r -gen js:node,runtime_package=woody_js/dist/thrift -o ./src/app/fistful ./node_modules/fistful-proto/proto/$(file).thrift;)
|
||||
@$(foreach file,withdrawal_session fistful_admin fistful_stat,echo $(file); thrift -r -gen js:node,runtime_package=woody_js/dist/thrift -o ./src/app/thrift-services/fistful ./node_modules/fistful-proto/proto/$(file).thrift;)
|
||||
|
||||
fistful-model:
|
||||
npm run fistful-model
|
||||
|
||||
compile-messages: messages-model messages-client
|
||||
|
||||
messages-client:
|
||||
@$(foreach file,messages,echo $(file); thrift -r -gen js:node,runtime_package=woody_js/dist/thrift -o ./src/app/thrift-services/messages ./node_modules/messages-proto/proto/$(file).thrift;)
|
||||
|
||||
messages-model:
|
||||
npm run messages-model
|
||||
|
||||
compile-file-storage: file-storage-model file-storage-client
|
||||
|
||||
file-storage-client:
|
||||
@$(foreach file,file_storage,echo $(file); thrift -r -gen js:node,runtime_package=woody_js/dist/thrift -o ./src/app/thrift-services/file-storage ./node_modules/file-storage-proto/proto/$(file).thrift;)
|
||||
|
||||
file-storage-model:
|
||||
npm run file-storage-model
|
||||
|
||||
compile-ank: ank-model ank-client
|
||||
|
||||
ank-client:
|
||||
@$(foreach file,questionary_manager,echo $(file); thrift -r -gen js:node,runtime_package=woody_js/dist/thrift -o ./src/app/thrift-services/ank ./node_modules/ank-proto/proto/$(file).thrift;)
|
||||
|
||||
ank-model:
|
||||
npm run ank-model
|
||||
|
||||
lint:
|
||||
npm run lint
|
||||
|
||||
|
293
package-lock.json
generated
293
package-lock.json
generated
@ -1720,6 +1720,12 @@
|
||||
"@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",
|
||||
@ -1735,6 +1741,12 @@
|
||||
"@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",
|
||||
@ -2207,6 +2219,11 @@
|
||||
"integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=",
|
||||
"dev": true
|
||||
},
|
||||
"angular-file": {
|
||||
"version": "1.3.2",
|
||||
"resolved": "https://registry.npmjs.org/angular-file/-/angular-file-1.3.2.tgz",
|
||||
"integrity": "sha512-k4HGJJ/JXGmNA8iV206I5WOHbufOy6L5f2MYHiUuGjlDiWjEJmjo8sxnNJsR79FzkjbL41TWRDAH2gi4VTUYKw=="
|
||||
},
|
||||
"angular2-prettyjson": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/angular2-prettyjson/-/angular2-prettyjson-3.0.1.tgz",
|
||||
@ -2215,6 +2232,10 @@
|
||||
"tslib": "^1.7.1"
|
||||
}
|
||||
},
|
||||
"ank-proto": {
|
||||
"version": "git+ssh://git@github.com/rbkmoney/ank-proto.git#9563a08d94c7691ec8f9166f78c05d68ae1e761d",
|
||||
"from": "git+ssh://git@github.com/rbkmoney/ank-proto.git#9563a08d94c7691ec8f9166f78c05d68ae1e761d"
|
||||
},
|
||||
"ansi-colors": {
|
||||
"version": "3.2.4",
|
||||
"resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.4.tgz",
|
||||
@ -4580,8 +4601,8 @@
|
||||
"dev": true
|
||||
},
|
||||
"damsel": {
|
||||
"version": "git+ssh://git@github.com/rbkmoney/damsel.git#b563890354447a5e175a9a318b33233a926a5e9c",
|
||||
"from": "git+ssh://git@github.com/rbkmoney/damsel.git#b563890354447a5e175a9a318b33233a926a5e9c"
|
||||
"version": "git+ssh://git@github.com/rbkmoney/damsel.git#7dd9035d89e8dab01d28e25445796c60503363a2",
|
||||
"from": "git+ssh://git@github.com/rbkmoney/damsel.git#7dd9035d89e8dab01d28e25445796c60503363a2"
|
||||
},
|
||||
"dashdash": {
|
||||
"version": "1.14.1",
|
||||
@ -4957,9 +4978,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"electron-to-chromium": {
|
||||
"version": "1.3.273",
|
||||
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.273.tgz",
|
||||
"integrity": "sha512-0kUppiHQvHEENHh+nTtvTt4eXMwcPyWmMaj73GPrSEm3ldKhmmHuOH6IjrmuW6YmyS/fpXcLvMQLNVpqRhpNWw=="
|
||||
"version": "1.3.344",
|
||||
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.344.tgz",
|
||||
"integrity": "sha512-tvbx2Wl8WBR+ym3u492D0L6/jH+8NoQXqe46+QhbWH3voVPauGuZYeb1QAXYoOAWuiP2dbSvlBx0kQ1F3hu/Mw=="
|
||||
},
|
||||
"elliptic": {
|
||||
"version": "6.5.1",
|
||||
@ -5530,6 +5551,10 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"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"
|
||||
},
|
||||
"file-uri-to-path": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz",
|
||||
@ -5665,8 +5690,8 @@
|
||||
}
|
||||
},
|
||||
"fistful-proto": {
|
||||
"version": "git+ssh://git@github.com/rbkmoney/fistful-proto.git#6e653a244e7b2106908604c4692ee5ab4496af09",
|
||||
"from": "git+ssh://git@github.com/rbkmoney/fistful-proto.git#6e653a244e7b2106908604c4692ee5ab4496af09"
|
||||
"version": "git+ssh://git@github.com/rbkmoney/fistful-proto.git#c2113c853ed71a34bb6468b9a6cf9b468967af84",
|
||||
"from": "git+ssh://git@github.com/rbkmoney/fistful-proto.git#c2113c853ed71a34bb6468b9a6cf9b468967af84"
|
||||
},
|
||||
"flake-idgen": {
|
||||
"version": "1.1.0",
|
||||
@ -6812,6 +6837,11 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"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",
|
||||
@ -7935,8 +7965,8 @@
|
||||
}
|
||||
},
|
||||
"machinegun_proto": {
|
||||
"version": "git+ssh://git@github.com/rbkmoney/machinegun_proto.git#ebae56fe2b3e79e4eb34afc8cb55c9012ae989f8",
|
||||
"from": "git+ssh://git@github.com/rbkmoney/machinegun_proto.git#ebae56fe2b3e79e4eb34afc8cb55c9012ae989f8"
|
||||
"version": "git+ssh://git@github.com/rbkmoney/machinegun_proto.git#eac772bb8446fcd2f439232bf10fa086c336aca6",
|
||||
"from": "git+ssh://git@github.com/rbkmoney/machinegun_proto.git#eac772bb8446fcd2f439232bf10fa086c336aca6"
|
||||
},
|
||||
"magic-string": {
|
||||
"version": "0.25.6",
|
||||
@ -8121,6 +8151,10 @@
|
||||
"integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==",
|
||||
"dev": true
|
||||
},
|
||||
"messages-proto": {
|
||||
"version": "git+ssh://git@github.com/rbkmoney/messages-proto.git#a177efb574136961bcd0a8236b4bfc425264de29",
|
||||
"from": "git+ssh://git@github.com/rbkmoney/messages-proto.git#a177efb574136961bcd0a8236b4bfc425264de29"
|
||||
},
|
||||
"methods": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
|
||||
@ -11300,9 +11334,9 @@
|
||||
}
|
||||
},
|
||||
"glob": {
|
||||
"version": "7.1.4",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz",
|
||||
"integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==",
|
||||
"version": "7.1.6",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
|
||||
"integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
|
||||
"requires": {
|
||||
"fs.realpath": "^1.0.0",
|
||||
"inflight": "^1.0.4",
|
||||
@ -11572,6 +11606,27 @@
|
||||
"integrity": "sha512-ACzBtm/PhXBDId6a6sDJfroT2pOWt/oOnk4/dElG5G33ZL776N3Y6/6bKZJBFpd+b05F3Ct9qDjMeJmRWtE2/g==",
|
||||
"dev": true
|
||||
},
|
||||
"uglify-es": {
|
||||
"version": "3.3.9",
|
||||
"resolved": "https://registry.npmjs.org/uglify-es/-/uglify-es-3.3.9.tgz",
|
||||
"integrity": "sha512-r+MU0rfv4L/0eeW3xZrd16t4NZfK8Ld4SWVglYBb7ez5uXFWHuVRs6xCTrf1yirs9a4j4Y27nn7SRfO6v67XsQ==",
|
||||
"requires": {
|
||||
"commander": "~2.13.0",
|
||||
"source-map": "~0.6.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"commander": {
|
||||
"version": "2.13.0",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-2.13.0.tgz",
|
||||
"integrity": "sha512-MVuS359B+YzaWqjCL/c+22gfryv+mCBPHAv3zyVI2GN8EY6IRP8VwtasXn8jyyhvvq84R4ImN1OKRtcbIasjYA=="
|
||||
},
|
||||
"source-map": {
|
||||
"version": "0.6.1",
|
||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
|
||||
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"uglifyjs-webpack-plugin": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/uglifyjs-webpack-plugin/-/uglifyjs-webpack-plugin-1.3.0.tgz",
|
||||
@ -11607,11 +11662,6 @@
|
||||
"y18n": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"commander": {
|
||||
"version": "2.13.0",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-2.13.0.tgz",
|
||||
"integrity": "sha512-MVuS359B+YzaWqjCL/c+22gfryv+mCBPHAv3zyVI2GN8EY6IRP8VwtasXn8jyyhvvq84R4ImN1OKRtcbIasjYA=="
|
||||
},
|
||||
"find-cache-dir": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-1.0.0.tgz",
|
||||
@ -11728,15 +11778,6 @@
|
||||
"requires": {
|
||||
"safe-buffer": "^5.1.1"
|
||||
}
|
||||
},
|
||||
"uglify-es": {
|
||||
"version": "3.3.9",
|
||||
"resolved": "https://registry.npmjs.org/uglify-es/-/uglify-es-3.3.9.tgz",
|
||||
"integrity": "sha512-r+MU0rfv4L/0eeW3xZrd16t4NZfK8Ld4SWVglYBb7ez5uXFWHuVRs6xCTrf1yirs9a4j4Y27nn7SRfO6v67XsQ==",
|
||||
"requires": {
|
||||
"commander": "~2.13.0",
|
||||
"source-map": "~0.6.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -12183,22 +12224,26 @@
|
||||
"dependencies": {
|
||||
"abbrev": {
|
||||
"version": "1.1.1",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
|
||||
"integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==",
|
||||
"optional": true
|
||||
},
|
||||
"ansi-regex": {
|
||||
"version": "2.1.1",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
|
||||
"integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
|
||||
"optional": true
|
||||
},
|
||||
"aproba": {
|
||||
"version": "1.2.0",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz",
|
||||
"integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==",
|
||||
"optional": true
|
||||
},
|
||||
"are-we-there-yet": {
|
||||
"version": "1.1.5",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz",
|
||||
"integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"delegates": "^1.0.0",
|
||||
@ -12207,12 +12252,14 @@
|
||||
},
|
||||
"balanced-match": {
|
||||
"version": "1.0.0",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
|
||||
"integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
|
||||
"optional": true
|
||||
},
|
||||
"brace-expansion": {
|
||||
"version": "1.1.11",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
||||
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"balanced-match": "^1.0.0",
|
||||
@ -12221,32 +12268,38 @@
|
||||
},
|
||||
"chownr": {
|
||||
"version": "1.1.1",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.1.tgz",
|
||||
"integrity": "sha512-j38EvO5+LHX84jlo6h4UzmOwi0UgW61WRyPtJz4qaadK5eY3BTS5TY/S1Stc3Uk2lIM6TPevAlULiEJwie860g==",
|
||||
"optional": true
|
||||
},
|
||||
"code-point-at": {
|
||||
"version": "1.1.0",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
|
||||
"integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=",
|
||||
"optional": true
|
||||
},
|
||||
"concat-map": {
|
||||
"version": "0.0.1",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
||||
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
|
||||
"optional": true
|
||||
},
|
||||
"console-control-strings": {
|
||||
"version": "1.1.0",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
|
||||
"integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=",
|
||||
"optional": true
|
||||
},
|
||||
"core-util-is": {
|
||||
"version": "1.0.2",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
|
||||
"integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=",
|
||||
"optional": true
|
||||
},
|
||||
"debug": {
|
||||
"version": "4.1.1",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
|
||||
"integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"ms": "^2.1.1"
|
||||
@ -12254,22 +12307,26 @@
|
||||
},
|
||||
"deep-extend": {
|
||||
"version": "0.6.0",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
|
||||
"integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==",
|
||||
"optional": true
|
||||
},
|
||||
"delegates": {
|
||||
"version": "1.0.0",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
|
||||
"integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=",
|
||||
"optional": true
|
||||
},
|
||||
"detect-libc": {
|
||||
"version": "1.0.3",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz",
|
||||
"integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=",
|
||||
"optional": true
|
||||
},
|
||||
"fs-minipass": {
|
||||
"version": "1.2.5",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.5.tgz",
|
||||
"integrity": "sha512-JhBl0skXjUPCFH7x6x61gQxrKyXsxB5gcgePLZCwfyCGGsTISMoIeObbrvVeP6Xmyaudw4TT43qV2Gz+iyd2oQ==",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"minipass": "^2.2.1"
|
||||
@ -12277,12 +12334,14 @@
|
||||
},
|
||||
"fs.realpath": {
|
||||
"version": "1.0.0",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
|
||||
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
|
||||
"optional": true
|
||||
},
|
||||
"gauge": {
|
||||
"version": "2.7.4",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz",
|
||||
"integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"aproba": "^1.0.3",
|
||||
@ -12297,7 +12356,8 @@
|
||||
},
|
||||
"glob": {
|
||||
"version": "7.1.3",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz",
|
||||
"integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"fs.realpath": "^1.0.0",
|
||||
@ -12310,12 +12370,14 @@
|
||||
},
|
||||
"has-unicode": {
|
||||
"version": "2.0.1",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz",
|
||||
"integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=",
|
||||
"optional": true
|
||||
},
|
||||
"iconv-lite": {
|
||||
"version": "0.4.24",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
|
||||
"integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"safer-buffer": ">= 2.1.2 < 3"
|
||||
@ -12323,7 +12385,8 @@
|
||||
},
|
||||
"ignore-walk": {
|
||||
"version": "3.0.1",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-3.0.1.tgz",
|
||||
"integrity": "sha512-DTVlMx3IYPe0/JJcYP7Gxg7ttZZu3IInhuEhbchuqneY9wWe5Ojy2mXLBaQFUQmo0AW2r3qG7m1mg86js+gnlQ==",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"minimatch": "^3.0.4"
|
||||
@ -12331,7 +12394,8 @@
|
||||
},
|
||||
"inflight": {
|
||||
"version": "1.0.6",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
|
||||
"integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"once": "^1.3.0",
|
||||
@ -12340,17 +12404,20 @@
|
||||
},
|
||||
"inherits": {
|
||||
"version": "2.0.3",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
|
||||
"integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
|
||||
"optional": true
|
||||
},
|
||||
"ini": {
|
||||
"version": "1.3.5",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz",
|
||||
"integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==",
|
||||
"optional": true
|
||||
},
|
||||
"is-fullwidth-code-point": {
|
||||
"version": "1.0.0",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
|
||||
"integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"number-is-nan": "^1.0.0"
|
||||
@ -12358,12 +12425,14 @@
|
||||
},
|
||||
"isarray": {
|
||||
"version": "1.0.0",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
|
||||
"integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
|
||||
"optional": true
|
||||
},
|
||||
"minimatch": {
|
||||
"version": "3.0.4",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
|
||||
"integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"brace-expansion": "^1.1.7"
|
||||
@ -12371,12 +12440,14 @@
|
||||
},
|
||||
"minimist": {
|
||||
"version": "0.0.8",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
|
||||
"integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=",
|
||||
"optional": true
|
||||
},
|
||||
"minipass": {
|
||||
"version": "2.3.5",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/minipass/-/minipass-2.3.5.tgz",
|
||||
"integrity": "sha512-Gi1W4k059gyRbyVUZQ4mEqLm0YIUiGYfvxhF6SIlk3ui1WVxMTGfGdQ2SInh3PDrRTVvPKgULkpJtT4RH10+VA==",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"safe-buffer": "^5.1.2",
|
||||
@ -12385,7 +12456,8 @@
|
||||
},
|
||||
"minizlib": {
|
||||
"version": "1.2.1",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.2.1.tgz",
|
||||
"integrity": "sha512-7+4oTUOWKg7AuL3vloEWekXY2/D20cevzsrNT2kGWm+39J9hGTCBv8VI5Pm5lXZ/o3/mdR4f8rflAPhnQb8mPA==",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"minipass": "^2.2.1"
|
||||
@ -12393,7 +12465,8 @@
|
||||
},
|
||||
"mkdirp": {
|
||||
"version": "0.5.1",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
|
||||
"integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"minimist": "0.0.8"
|
||||
@ -12401,12 +12474,14 @@
|
||||
},
|
||||
"ms": {
|
||||
"version": "2.1.1",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
|
||||
"integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==",
|
||||
"optional": true
|
||||
},
|
||||
"needle": {
|
||||
"version": "2.3.0",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/needle/-/needle-2.3.0.tgz",
|
||||
"integrity": "sha512-QBZu7aAFR0522EyaXZM0FZ9GLpq6lvQ3uq8gteiDUp7wKdy0lSd2hPlgFwVuW1CBkfEs9PfDQsQzZghLs/psdg==",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"debug": "^4.1.0",
|
||||
@ -12416,7 +12491,8 @@
|
||||
},
|
||||
"node-pre-gyp": {
|
||||
"version": "0.12.0",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/node-pre-gyp/-/node-pre-gyp-0.12.0.tgz",
|
||||
"integrity": "sha512-4KghwV8vH5k+g2ylT+sLTjy5wmUOb9vPhnM8NHvRf9dHmnW/CndrFXy2aRPaPST6dugXSdHXfeaHQm77PIz/1A==",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"detect-libc": "^1.0.2",
|
||||
@ -12433,7 +12509,8 @@
|
||||
},
|
||||
"nopt": {
|
||||
"version": "4.0.1",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.1.tgz",
|
||||
"integrity": "sha1-0NRoWv1UFRk8jHUFYC0NF81kR00=",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"abbrev": "1",
|
||||
@ -12442,12 +12519,14 @@
|
||||
},
|
||||
"npm-bundled": {
|
||||
"version": "1.0.6",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-1.0.6.tgz",
|
||||
"integrity": "sha512-8/JCaftHwbd//k6y2rEWp6k1wxVfpFzB6t1p825+cUb7Ym2XQfhwIC5KwhrvzZRJu+LtDE585zVaS32+CGtf0g==",
|
||||
"optional": true
|
||||
},
|
||||
"npm-packlist": {
|
||||
"version": "1.4.1",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-1.4.1.tgz",
|
||||
"integrity": "sha512-+TcdO7HJJ8peiiYhvPxsEDhF3PJFGUGRcFsGve3vxvxdcpO2Z4Z7rkosRM0kWj6LfbK/P0gu3dzk5RU1ffvFcw==",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"ignore-walk": "^3.0.1",
|
||||
@ -12456,7 +12535,8 @@
|
||||
},
|
||||
"npmlog": {
|
||||
"version": "4.1.2",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz",
|
||||
"integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"are-we-there-yet": "~1.1.2",
|
||||
@ -12467,17 +12547,20 @@
|
||||
},
|
||||
"number-is-nan": {
|
||||
"version": "1.0.1",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
|
||||
"integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=",
|
||||
"optional": true
|
||||
},
|
||||
"object-assign": {
|
||||
"version": "4.1.1",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
|
||||
"integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
|
||||
"optional": true
|
||||
},
|
||||
"once": {
|
||||
"version": "1.4.0",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
|
||||
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"wrappy": "1"
|
||||
@ -12485,17 +12568,20 @@
|
||||
},
|
||||
"os-homedir": {
|
||||
"version": "1.0.2",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz",
|
||||
"integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=",
|
||||
"optional": true
|
||||
},
|
||||
"os-tmpdir": {
|
||||
"version": "1.0.2",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
|
||||
"integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=",
|
||||
"optional": true
|
||||
},
|
||||
"osenv": {
|
||||
"version": "0.1.5",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz",
|
||||
"integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"os-homedir": "^1.0.0",
|
||||
@ -12504,17 +12590,20 @@
|
||||
},
|
||||
"path-is-absolute": {
|
||||
"version": "1.0.1",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
|
||||
"integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
|
||||
"optional": true
|
||||
},
|
||||
"process-nextick-args": {
|
||||
"version": "2.0.0",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz",
|
||||
"integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==",
|
||||
"optional": true
|
||||
},
|
||||
"rc": {
|
||||
"version": "1.2.8",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz",
|
||||
"integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"deep-extend": "^0.6.0",
|
||||
@ -12525,14 +12614,16 @@
|
||||
"dependencies": {
|
||||
"minimist": {
|
||||
"version": "1.2.0",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
|
||||
"integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"readable-stream": {
|
||||
"version": "2.3.6",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
|
||||
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"core-util-is": "~1.0.0",
|
||||
@ -12546,7 +12637,8 @@
|
||||
},
|
||||
"rimraf": {
|
||||
"version": "2.6.3",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz",
|
||||
"integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"glob": "^7.1.3"
|
||||
@ -12554,37 +12646,44 @@
|
||||
},
|
||||
"safe-buffer": {
|
||||
"version": "5.1.2",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
|
||||
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
|
||||
"optional": true
|
||||
},
|
||||
"safer-buffer": {
|
||||
"version": "2.1.2",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
|
||||
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
|
||||
"optional": true
|
||||
},
|
||||
"sax": {
|
||||
"version": "1.2.4",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz",
|
||||
"integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==",
|
||||
"optional": true
|
||||
},
|
||||
"semver": {
|
||||
"version": "5.7.0",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz",
|
||||
"integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==",
|
||||
"optional": true
|
||||
},
|
||||
"set-blocking": {
|
||||
"version": "2.0.0",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
|
||||
"integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=",
|
||||
"optional": true
|
||||
},
|
||||
"signal-exit": {
|
||||
"version": "3.0.2",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz",
|
||||
"integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=",
|
||||
"optional": true
|
||||
},
|
||||
"string-width": {
|
||||
"version": "1.0.2",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
|
||||
"integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"code-point-at": "^1.0.0",
|
||||
@ -12594,7 +12693,8 @@
|
||||
},
|
||||
"string_decoder": {
|
||||
"version": "1.1.1",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
|
||||
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"safe-buffer": "~5.1.0"
|
||||
@ -12602,7 +12702,8 @@
|
||||
},
|
||||
"strip-ansi": {
|
||||
"version": "3.0.1",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
|
||||
"integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"ansi-regex": "^2.0.0"
|
||||
@ -12610,12 +12711,14 @@
|
||||
},
|
||||
"strip-json-comments": {
|
||||
"version": "2.0.1",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
|
||||
"integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=",
|
||||
"optional": true
|
||||
},
|
||||
"tar": {
|
||||
"version": "4.4.8",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/tar/-/tar-4.4.8.tgz",
|
||||
"integrity": "sha512-LzHF64s5chPQQS0IYBn9IN5h3i98c12bo4NCO7e0sGM2llXQ3p2FGC5sdENN4cTW48O915Sh+x+EXx7XW96xYQ==",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"chownr": "^1.1.1",
|
||||
@ -12629,12 +12732,14 @@
|
||||
},
|
||||
"util-deprecate": {
|
||||
"version": "1.0.2",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
||||
"integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
|
||||
"optional": true
|
||||
},
|
||||
"wide-align": {
|
||||
"version": "1.1.3",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz",
|
||||
"integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"string-width": "^1.0.2 || 2"
|
||||
@ -12642,12 +12747,14 @@
|
||||
},
|
||||
"wrappy": {
|
||||
"version": "1.0.2",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
||||
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
|
||||
"optional": true
|
||||
},
|
||||
"yallist": {
|
||||
"version": "3.0.3",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz",
|
||||
"integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==",
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
@ -13359,7 +13466,7 @@
|
||||
},
|
||||
"stream-http": {
|
||||
"version": "2.3.1",
|
||||
"resolved": "http://registry.npmjs.org/stream-http/-/stream-http-2.3.1.tgz",
|
||||
"resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.3.1.tgz",
|
||||
"integrity": "sha1-fh3IcQLD4xsy5mDwTKMfI929HVI=",
|
||||
"requires": {
|
||||
"builtin-status-codes": "^2.0.0",
|
||||
|
24
package.json
24
package.json
@ -8,10 +8,13 @@
|
||||
"test": "ng test",
|
||||
"lint": "ng lint",
|
||||
"e2e": "ng e2e",
|
||||
"damsel-model": "thrift-ts node_modules/damsel/proto -o src/app/gen-damsel -d false",
|
||||
"damsel-model": "thrift-ts node_modules/damsel/proto -o src/app/thrift-services/damsel/gen-model -d false",
|
||||
"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",
|
||||
"machinegun-model": "thrift-ts node_modules/machinegun_proto/proto -o src/app/thrift-services/machinegun/gen-model -d false",
|
||||
"fistful-model": "thrift-ts node_modules/fistful-proto/proto -o src/app/thrift-services/fistful/gen-model -d false",
|
||||
"messages-model": "thrift-ts node_modules/messages-proto/proto -o src/app/thrift-services/messages/gen-model -d false",
|
||||
"file-storage-model": "thrift-ts node_modules/file-storage-proto/proto -o src/app/thrift-services/file-storage/gen-model -d false",
|
||||
"ank-model": "thrift-ts node_modules/ank-proto/proto -o src/app/thrift-services/ank/gen-model -d false",
|
||||
"prettier": "prettier \"**/*.{html,js,ts,css,md,json,prettierrc,svg}\" --write",
|
||||
"check": "prettier \"**/*.{html,js,ts,css,md,json,prettierrc,svg}\" --list-different"
|
||||
},
|
||||
@ -31,19 +34,24 @@
|
||||
"@angular/platform-server": "~8.2.14",
|
||||
"@angular/router": "~8.2.14",
|
||||
"@rbkmoney/partial-fetcher": "~1.0.4",
|
||||
"angular-file": "1.3.2",
|
||||
"angular2-prettyjson": "3.0.1",
|
||||
"core-js": "~2.5.4",
|
||||
"damsel": "git+ssh://git@github.com/rbkmoney/damsel.git#b563890354447a5e175a9a318b33233a926a5e9c",
|
||||
"fistful-proto": "git+ssh://git@github.com/rbkmoney/fistful-proto.git#6e653a244e7b2106908604c4692ee5ab4496af09",
|
||||
"damsel": "git+ssh://git@github.com/rbkmoney/damsel.git#7dd9035d89e8dab01d28e25445796c60503363a2",
|
||||
"ank-proto": "git+ssh://git@github.com:rbkmoney/ank-proto.git#9563a08d94c7691ec8f9166f78c05d68ae1e761d",
|
||||
"file-storage-proto": "git+ssh://git@github.com:rbkmoney/file-storage-proto.git#281e1ca4cea9bf32229a6c389f0dcf5d49c05a0b",
|
||||
"fistful-proto": "git+ssh://git@github.com/rbkmoney/fistful-proto.git#c2113c853ed71a34bb6468b9a6cf9b468967af84",
|
||||
"hammerjs": "~2.0.8",
|
||||
"humanize-duration": "~3.21.0",
|
||||
"jsonc-parser": "~2.0.2",
|
||||
"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",
|
||||
"machinegun_proto": "git+ssh://git@github.com/rbkmoney/machinegun_proto.git#eac772bb8446fcd2f439232bf10fa086c336aca6",
|
||||
"rxjs": "~6.5.4",
|
||||
"messages-proto": "git+ssh://git@github.com:rbkmoney/messages-proto.git#a177efb574136961bcd0a8236b4bfc425264de29",
|
||||
"moment": "~2.22.2",
|
||||
"monaco-editor": "~0.15.6",
|
||||
"rxjs": "~6.5.4",
|
||||
"thrift-ts": "git+ssh://git@github.com/rbkmoney/thrift-ts.git#a5e3830ad30d5717e5e627ddcefa8f4d8918b174",
|
||||
"uuid": "~3.3.2",
|
||||
"woody_js": "git+ssh://git@github.com/rbkmoney/woody_js.git#bc2c9f86cae470a0fe99730ca4a30b204058214b",
|
||||
@ -53,8 +61,10 @@
|
||||
"@angular-devkit/build-angular": "~0.803.23",
|
||||
"@angular/cli": "~8.3.23",
|
||||
"@angular/compiler-cli": "~8.2.14",
|
||||
"@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",
|
||||
|
@ -1,24 +1,30 @@
|
||||
{
|
||||
"/v1": {
|
||||
"target": "http://iddqd.rbk.test:8080",
|
||||
"target": "https://iddqd.rbk.money",
|
||||
"secure": false,
|
||||
"logLevel": "debug",
|
||||
"changeOrigin": true
|
||||
},
|
||||
"/stat": {
|
||||
"target": "http://iddqd.rbk.test:8080",
|
||||
"target": "https://iddqd.rbk.money",
|
||||
"secure": false,
|
||||
"logLevel": "debug",
|
||||
"changeOrigin": true
|
||||
},
|
||||
"/fistful/stat": {
|
||||
"target": "http://iddqd.rbk.test:8080",
|
||||
"target": "https://iddqd.rbk.money",
|
||||
"secure": false,
|
||||
"logLevel": "debug",
|
||||
"changeOrigin": true
|
||||
},
|
||||
"/papi/v1": {
|
||||
"target": "http://iddqd.rbk.test:8080",
|
||||
"target": "https://iddqd.rbk.money",
|
||||
"secure": false,
|
||||
"logLevel": "debug",
|
||||
"changeOrigin": true
|
||||
},
|
||||
"/file_storage": {
|
||||
"target": "https://iddqd.rbk.money",
|
||||
"secure": false,
|
||||
"logLevel": "debug",
|
||||
"changeOrigin": true
|
||||
|
@ -27,6 +27,7 @@ export class AppComponent implements OnInit {
|
||||
{ name: 'Domain config', route: '/domain', activateRole: 'dmt:checkout' },
|
||||
{ name: 'Payouts', route: '/payouts', activateRole: 'payout:read' },
|
||||
{ name: 'Claims', route: '/claims', activateRole: 'claim:get' },
|
||||
{ name: 'Claim-MGT', route: '/claim-mgt', activateRole: 'claim:get' },
|
||||
{
|
||||
name: 'Payment adjustment',
|
||||
route: '/payment-adjustment',
|
||||
|
@ -30,6 +30,7 @@ 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],
|
||||
@ -52,7 +53,8 @@ import { DepositsModule } from './deposits/deposits.module';
|
||||
PartyModule,
|
||||
DomainModule,
|
||||
RepairingModule,
|
||||
DepositsModule
|
||||
DepositsModule,
|
||||
ClaimMgtModule
|
||||
],
|
||||
providers: [
|
||||
{ provide: MAT_MOMENT_DATE_ADAPTER_OPTIONS, useValue: { useUtc: true } },
|
||||
|
29
src/app/claim-mgt/claim-mgt-routing.module.ts
Normal file
29
src/app/claim-mgt/claim-mgt-routing.module.ts
Normal file
@ -0,0 +1,29 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { RouterModule } from '@angular/router';
|
||||
import { AppAuthGuardService } from '../app-auth-guard.service';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
RouterModule.forChild([
|
||||
{ path: 'claim-mgt', redirectTo: 'claim-mgt/claims', pathMatch: 'full' },
|
||||
{
|
||||
path: 'claim-mgt/claims',
|
||||
loadChildren: () => import('./claims').then(m => m.ClaimsModule),
|
||||
canActivate: [AppAuthGuardService],
|
||||
data: {
|
||||
roles: ['claim:get']
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'claim-mgt/party',
|
||||
loadChildren: () => import('./claim').then(m => m.ClaimModule),
|
||||
canActivate: [AppAuthGuardService],
|
||||
data: {
|
||||
roles: ['claim:get']
|
||||
}
|
||||
}
|
||||
])
|
||||
],
|
||||
exports: [RouterModule]
|
||||
})
|
||||
export class ClaimMgtRouting {}
|
8
src/app/claim-mgt/claim-mgt.module.ts
Normal file
8
src/app/claim-mgt/claim-mgt.module.ts
Normal file
@ -0,0 +1,8 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
|
||||
import { ClaimMgtRouting } from './claim-mgt-routing.module';
|
||||
|
||||
@NgModule({
|
||||
imports: [ClaimMgtRouting]
|
||||
})
|
||||
export class ClaimMgtModule {}
|
21
src/app/claim-mgt/claim/claim-routing.module.ts
Normal file
21
src/app/claim-mgt/claim/claim-routing.module.ts
Normal file
@ -0,0 +1,21 @@
|
||||
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 {}
|
7
src/app/claim-mgt/claim/claim-statuses.ts
Normal file
7
src/app/claim-mgt/claim/claim-statuses.ts
Normal file
@ -0,0 +1,7 @@
|
||||
export enum ClaimStatuses {
|
||||
'pending_acceptance' = 'pending_acceptance',
|
||||
'pending' = 'pending',
|
||||
'revoked' = 'revoked',
|
||||
'denied' = 'denied',
|
||||
'review' = 'review'
|
||||
}
|
7
src/app/claim-mgt/claim/claim.component.html
Normal file
7
src/app/claim-mgt/claim/claim.component.html
Normal file
@ -0,0 +1,7 @@
|
||||
<cc-card-container *ngIf="(claim$ | async) as claim">
|
||||
<cc-claim-details [claim]="claim"></cc-claim-details>
|
||||
<cc-claim-conversation
|
||||
[claim]="claim"
|
||||
(conversationChangedEvent)="conversationChanged()"
|
||||
></cc-claim-conversation>
|
||||
</cc-card-container>
|
27
src/app/claim-mgt/claim/claim.component.ts
Normal file
27
src/app/claim-mgt/claim/claim.component.ts
Normal file
@ -0,0 +1,27 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import Int64 from 'thrift-ts/lib/int64';
|
||||
|
||||
import { ClaimService } from './claim.service';
|
||||
|
||||
@Component({
|
||||
templateUrl: 'claim.component.html'
|
||||
})
|
||||
export class ClaimComponent {
|
||||
claim$ = this.claimService.claim$;
|
||||
|
||||
constructor(private route: ActivatedRoute, private claimService: ClaimService) {
|
||||
this.getClaim();
|
||||
}
|
||||
|
||||
conversationChanged() {
|
||||
this.getClaim();
|
||||
}
|
||||
|
||||
private getClaim() {
|
||||
this.route.params.subscribe(params => {
|
||||
const { party_id, claim_id } = params;
|
||||
this.claimService.getClaim(party_id, new Int64(Number(claim_id)));
|
||||
});
|
||||
}
|
||||
}
|
62
src/app/claim-mgt/claim/claim.module.ts
Normal file
62
src/app/claim-mgt/claim/claim.module.ts
Normal file
@ -0,0 +1,62 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { FlexModule } from '@angular/flex-layout';
|
||||
import {
|
||||
MatCardModule,
|
||||
MatSelectModule,
|
||||
MatButtonModule,
|
||||
MatDialogModule,
|
||||
MatProgressBarModule,
|
||||
MatInputModule
|
||||
} from '@angular/material';
|
||||
import { ReactiveFormsModule } from '@angular/forms';
|
||||
import { MatListModule } from '@angular/material/list';
|
||||
import { MatBottomSheetModule } from '@angular/material/bottom-sheet';
|
||||
import { MatStepperModule } from '@angular/material/stepper';
|
||||
|
||||
import { ClaimComponent } from './claim.component';
|
||||
import { ClaimRoutingModule } from './claim-routing.module';
|
||||
import { SharedModule } from '../../shared/shared.module';
|
||||
import { DetailsComponent } from './details/details.component';
|
||||
import { ConversationModule } from './conversation/conversation.module';
|
||||
import { StatusChangerComponent } from './status-changer/status-changer.component';
|
||||
import { PartyModificationTargetModule } from '../../party-modification-target';
|
||||
import { ClaimManagementService } from '../../thrift-services/damsel/claim-management.service';
|
||||
import { UnitActionsComponent } from './party-modification-creator/unit-actions/unit-actions.component';
|
||||
import { ContainerNamePipe } from './party-modification-creator/container-name.pipe';
|
||||
import { PartyModificationCreationModule } from './party-modification-creator/creation';
|
||||
import { CreateModificationComponent } from './party-modification-creator/create-modification.component';
|
||||
import { ClaimService } from './claim.service';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
ClaimRoutingModule,
|
||||
SharedModule,
|
||||
CommonModule,
|
||||
MatCardModule,
|
||||
FlexModule,
|
||||
MatSelectModule,
|
||||
ConversationModule,
|
||||
MatButtonModule,
|
||||
MatDialogModule,
|
||||
MatProgressBarModule,
|
||||
ReactiveFormsModule,
|
||||
MatInputModule,
|
||||
MatListModule,
|
||||
MatBottomSheetModule,
|
||||
MatStepperModule,
|
||||
PartyModificationTargetModule,
|
||||
PartyModificationCreationModule
|
||||
],
|
||||
declarations: [
|
||||
ClaimComponent,
|
||||
DetailsComponent,
|
||||
StatusChangerComponent,
|
||||
CreateModificationComponent,
|
||||
ContainerNamePipe,
|
||||
UnitActionsComponent
|
||||
],
|
||||
entryComponents: [StatusChangerComponent, CreateModificationComponent, UnitActionsComponent],
|
||||
providers: [ClaimManagementService, ClaimService]
|
||||
})
|
||||
export class ClaimModule {}
|
26
src/app/claim-mgt/claim/claim.service.ts
Normal file
26
src/app/claim-mgt/claim/claim.service.ts
Normal file
@ -0,0 +1,26 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Subject } from 'rxjs';
|
||||
import { MatSnackBar } from '@angular/material';
|
||||
|
||||
import { ClaimManagementService } from '../../thrift-services/damsel/claim-management.service';
|
||||
import { Claim, ClaimID } from '../../thrift-services/damsel/gen-model/claim_management';
|
||||
|
||||
@Injectable()
|
||||
export class ClaimService {
|
||||
claim$: Subject<Claim> = new Subject();
|
||||
|
||||
constructor(
|
||||
private claimManagementService: ClaimManagementService,
|
||||
private snackBar: MatSnackBar
|
||||
) {}
|
||||
|
||||
getClaim(partyID: string, claimID: ClaimID) {
|
||||
this.claimManagementService.getClaim(partyID, claimID).subscribe(
|
||||
claim => this.claim$.next(claim),
|
||||
e => {
|
||||
console.error(e);
|
||||
this.snackBar.open('Error loading the claim', 'OK');
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
21
src/app/claim-mgt/claim/conversation/action-icon.pipe.ts
Normal file
21
src/app/claim-mgt/claim/conversation/action-icon.pipe.ts
Normal file
@ -0,0 +1,21 @@
|
||||
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];
|
||||
}
|
||||
}
|
21
src/app/claim-mgt/claim/conversation/action-name.pipe.ts
Normal file
21
src/app/claim-mgt/claim/conversation/action-name.pipe.ts
Normal file
@ -0,0 +1,21 @@
|
||||
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];
|
||||
}
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
<mat-card>
|
||||
<mat-card-content>
|
||||
{{ conversation ? conversation.messages[0].text : "Can't load conversation" }}
|
||||
</mat-card-content>
|
||||
</mat-card>
|
@ -0,0 +1,3 @@
|
||||
mat-card-content {
|
||||
word-break: break-all;
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
import { Component, Input } from '@angular/core';
|
||||
|
||||
import { Conversation } from '../../../../thrift-services/messages/gen-model/messages';
|
||||
|
||||
@Component({
|
||||
selector: 'cc-conversation-comment',
|
||||
templateUrl: 'comment.component.html',
|
||||
styleUrls: ['comment.component.scss']
|
||||
})
|
||||
export class CommentComponent {
|
||||
@Input() conversation: Conversation;
|
||||
}
|
@ -0,0 +1,74 @@
|
||||
<div fxLayout="column" fxLayoutGap="20px">
|
||||
<cc-timeline *ngIf="(timelineInfo$ | async) as timelineInfo">
|
||||
<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"
|
||||
>
|
||||
<ng-container *ngFor="let m of item.modifications">
|
||||
<cc-file-container
|
||||
*ngIf="item.action === timelineAction.filesAdded"
|
||||
[fileID]="m.claim_modification.file_modification.id"
|
||||
></cc-file-container>
|
||||
<cc-conversation-comment
|
||||
*ngIf="item.action === timelineAction.commentAdded"
|
||||
[conversation]="item.data"
|
||||
></cc-conversation-comment>
|
||||
<cc-reason
|
||||
*ngIf="
|
||||
item.action === timelineAction.statusDenied ||
|
||||
item.action === timelineAction.statusRevoked
|
||||
"
|
||||
[statusModificationUnit]="m.claim_modification.status_modification"
|
||||
></cc-reason>
|
||||
<cc-questionary
|
||||
*ngIf="item.action === timelineAction.changesAdded"
|
||||
[questionary]="questionary$ | async"
|
||||
></cc-questionary>
|
||||
</ng-container>
|
||||
<ng-container
|
||||
*ngIf="
|
||||
item.action !== timelineAction.statusRevoked ||
|
||||
item.action !== timelineAction.statusDenied
|
||||
"
|
||||
>
|
||||
<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>
|
||||
</ng-container>
|
||||
</cc-timeline-item-content>
|
||||
</cc-timeline-item>
|
||||
</cc-timeline>
|
||||
<div fxLayout="row" fxLayoutGap="10px" fxLayoutAlign="space-between center">
|
||||
<cc-file-uploader
|
||||
(filesUploaded)="updateConversation(timelineAction.filesAdded, $event)"
|
||||
></cc-file-uploader>
|
||||
<cc-send-comment
|
||||
fxFlex="100"
|
||||
*ngIf="claimStatus !== claimStatuses.denied && claimStatus !== claimStatuses.revoked"
|
||||
(conversationSaved)="updateConversation(timelineAction.commentAdded, $event)"
|
||||
></cc-send-comment>
|
||||
</div>
|
||||
</div>
|
@ -0,0 +1,48 @@
|
||||
import { Component, EventEmitter, Input, OnChanges, Output, SimpleChanges } from '@angular/core';
|
||||
|
||||
import { Modification, Claim } from '../../../thrift-services/damsel/gen-model/claim_management';
|
||||
import { ConversationService } from './conversation.service';
|
||||
import { extractClaimStatus } from '../../../shared/extract-claim-status';
|
||||
import { ClaimStatus } from '../../../papi/model';
|
||||
import { TimelineAction } from './to-timeline-info/model';
|
||||
import { QuestionaryService } from './questionary.service';
|
||||
import { getUnionKey } from '../../../shared/get-union-key';
|
||||
|
||||
@Component({
|
||||
selector: 'cc-claim-conversation',
|
||||
templateUrl: 'conversation.component.html',
|
||||
providers: [ConversationService, QuestionaryService]
|
||||
})
|
||||
export class ConversationComponent implements OnChanges {
|
||||
@Input() claim: Claim;
|
||||
@Output() conversationChangedEvent = new EventEmitter();
|
||||
|
||||
timelineInfo$ = this.conversationService.timelineInfos$;
|
||||
questionary$ = this.questionaryService.questionary$;
|
||||
timelineAction = TimelineAction;
|
||||
claimStatus: ClaimStatus;
|
||||
claimStatuses = ClaimStatus;
|
||||
|
||||
constructor(
|
||||
private conversationService: ConversationService,
|
||||
private questionaryService: QuestionaryService
|
||||
) {}
|
||||
|
||||
ngOnChanges(changes: SimpleChanges) {
|
||||
const { currentValue } = changes.claim;
|
||||
if (currentValue) {
|
||||
this.claimStatus = extractClaimStatus(currentValue.status);
|
||||
this.conversationService.enrichWithData(currentValue.changeset);
|
||||
}
|
||||
}
|
||||
|
||||
updateConversation(action: TimelineAction, modifications: Modification[]) {
|
||||
this.conversationService
|
||||
.updateConversation(this.claim.party_id, this.claim.id, action, modifications)
|
||||
.subscribe(_ => this.conversationChangedEvent.emit());
|
||||
}
|
||||
|
||||
getKey(modification: Modification) {
|
||||
return getUnionKey(modification);
|
||||
}
|
||||
}
|
67
src/app/claim-mgt/claim/conversation/conversation.module.ts
Normal file
67
src/app/claim-mgt/claim/conversation/conversation.module.ts
Normal file
@ -0,0 +1,67 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { FlexLayoutModule } from '@angular/flex-layout';
|
||||
import {
|
||||
MatButtonModule,
|
||||
MatExpansionModule,
|
||||
MatFormFieldModule,
|
||||
MatIconModule,
|
||||
MatInputModule
|
||||
} from '@angular/material';
|
||||
import { MatSelectModule } from '@angular/material/select';
|
||||
import { ReactiveFormsModule } from '@angular/forms';
|
||||
import { LayoutModule } from '@angular/cdk/layout';
|
||||
import { MatCardModule } from '@angular/material/card';
|
||||
|
||||
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';
|
||||
import { SendCommentComponent } from './send-comment';
|
||||
import { MessagesModule } from '../../../thrift-services/messages';
|
||||
import { CommentComponent } from './comment/comment.component';
|
||||
import { ReasonComponent } from './reason/reason.component';
|
||||
import { FileContainerModule } from './file-container';
|
||||
import { FileUploaderModule } from './file-uploader/file-uploader.module';
|
||||
import { QuestionaryComponent } from './questionary';
|
||||
import { AnkModule } from '../../../thrift-services';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
LayoutModule,
|
||||
MatButtonModule,
|
||||
FlexLayoutModule,
|
||||
MatFormFieldModule,
|
||||
MatInputModule,
|
||||
TimelineModule,
|
||||
MatIconModule,
|
||||
SharedModule,
|
||||
CommonModule,
|
||||
ReactiveFormsModule,
|
||||
SharedModule,
|
||||
MatExpansionModule,
|
||||
MonacoEditorModule,
|
||||
HumanizeDurationModule,
|
||||
MessagesModule,
|
||||
MatCardModule,
|
||||
HumanizeDurationModule,
|
||||
MatSelectModule,
|
||||
FileContainerModule,
|
||||
FileUploaderModule,
|
||||
AnkModule
|
||||
],
|
||||
declarations: [
|
||||
ConversationComponent,
|
||||
ReasonComponent,
|
||||
SendCommentComponent,
|
||||
ActionIconPipe,
|
||||
ActionNamePipe,
|
||||
CommentComponent,
|
||||
QuestionaryComponent
|
||||
],
|
||||
exports: [ConversationComponent]
|
||||
})
|
||||
export class ConversationModule {}
|
61
src/app/claim-mgt/claim/conversation/conversation.service.ts
Normal file
61
src/app/claim-mgt/claim/conversation/conversation.service.ts
Normal file
@ -0,0 +1,61 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { from, Observable, Subject } from 'rxjs';
|
||||
import { catchError, map } from 'rxjs/operators';
|
||||
import flatten from 'lodash-es/flatten';
|
||||
|
||||
import { TimelineAction, TimelineItemInfo } from './to-timeline-info/model';
|
||||
import {
|
||||
ClaimChangeset,
|
||||
ClaimID,
|
||||
Modification
|
||||
} from '../../../thrift-services/damsel/gen-model/claim_management';
|
||||
import { ClaimManagementService } from '../../../thrift-services/damsel/claim-management.service';
|
||||
import { toTimelineInfo } from './to-timeline-info';
|
||||
import { MessagesService } from '../../../thrift-services/messages/messages.service';
|
||||
import { ConversationId } from '../../../thrift-services/messages/gen-model/messages';
|
||||
import { addCommentsToTimelineInfos } from './to-timeline-info';
|
||||
|
||||
@Injectable()
|
||||
export class ConversationService {
|
||||
timelineInfos$ = new Subject<TimelineItemInfo[]>();
|
||||
|
||||
constructor(
|
||||
private claimManagementService: ClaimManagementService,
|
||||
private messagesService: MessagesService
|
||||
) {}
|
||||
|
||||
updateConversation(
|
||||
party_id: string,
|
||||
claim_id: ClaimID,
|
||||
action: TimelineAction,
|
||||
modifications: Modification[]
|
||||
): Observable<void> {
|
||||
return this.claimManagementService.updateClaim(party_id, claim_id, modifications);
|
||||
}
|
||||
|
||||
enrichWithData(changeset: ClaimChangeset) {
|
||||
from(this.addCommentsToInfo(toTimelineInfo(changeset))).subscribe(infos =>
|
||||
this.timelineInfos$.next(infos)
|
||||
);
|
||||
}
|
||||
|
||||
private addCommentsToInfo(timelineInfos: TimelineItemInfo[]): Observable<TimelineItemInfo[]> {
|
||||
const commentAddedIds: ConversationId[] = flatten(
|
||||
timelineInfos
|
||||
.filter(info => info.action === TimelineAction.commentAdded)
|
||||
.map((commentInfo: TimelineItemInfo) =>
|
||||
commentInfo.modifications.map(m => m.claim_modification.comment_modification.id)
|
||||
)
|
||||
);
|
||||
|
||||
return this.messagesService.getConversations(commentAddedIds, {}).pipe(
|
||||
map(conversationsResponse =>
|
||||
addCommentsToTimelineInfos(conversationsResponse.conversations, timelineInfos)
|
||||
),
|
||||
catchError(e => {
|
||||
console.error(e);
|
||||
return [timelineInfos];
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
/**
|
||||
* 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);
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
.download-icon {
|
||||
color: rgba(0, 0, 0, 0.87);
|
||||
}
|
||||
|
||||
.download-icon:hover {
|
||||
cursor: pointer;
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
<mat-card *ngIf="(fileData$ | async) as fileData">
|
||||
<mat-card-content fxLayout="row" fxLayoutAlign="space-between">
|
||||
<div class="mat-body-1">{{ fileData.file_name }}</div>
|
||||
<mat-icon class="download-icon" (click)="downloadFile()">cloud_download</mat-icon>
|
||||
</mat-card-content>
|
||||
</mat-card>
|
@ -0,0 +1,26 @@
|
||||
import { Component, Input, OnInit } from '@angular/core';
|
||||
|
||||
import { FileContainerService } from './file-container.service';
|
||||
|
||||
@Component({
|
||||
selector: 'cc-file-container',
|
||||
templateUrl: 'file-container.component.html',
|
||||
styleUrls: ['file-container.component.css'],
|
||||
providers: [FileContainerService]
|
||||
})
|
||||
export class FileContainerComponent implements OnInit {
|
||||
@Input()
|
||||
fileID: string;
|
||||
|
||||
fileData$ = this.fileContainerService.fileData$;
|
||||
|
||||
constructor(private fileContainerService: FileContainerService) {}
|
||||
|
||||
ngOnInit() {
|
||||
this.fileContainerService.getFileInfo(this.fileID);
|
||||
}
|
||||
|
||||
downloadFile() {
|
||||
this.fileContainerService.downloadFile(this.fileID);
|
||||
}
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { FlexModule } from '@angular/flex-layout';
|
||||
import { MatCardModule } from '@angular/material';
|
||||
import { MatIconModule } from '@angular/material/icon';
|
||||
|
||||
import { FileContainerComponent } from './file-container.component';
|
||||
import { FileStorageService } from '../../../../thrift-services/file-storage/file-storage.service';
|
||||
|
||||
@NgModule({
|
||||
imports: [CommonModule, MatCardModule, FlexModule, MatIconModule],
|
||||
exports: [FileContainerComponent],
|
||||
declarations: [FileContainerComponent],
|
||||
providers: [FileStorageService]
|
||||
})
|
||||
export class FileContainerModule {}
|
@ -0,0 +1,56 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { MatSnackBar } from '@angular/material';
|
||||
import { Observable, Subject } from 'rxjs';
|
||||
import { shareReplay, switchMap } from 'rxjs/operators';
|
||||
import * as moment from 'moment';
|
||||
|
||||
import { FileStorageService } from '../../../../thrift-services/file-storage/file-storage.service';
|
||||
import {
|
||||
FileData,
|
||||
FileNotFound
|
||||
} from '../../../../thrift-services/file-storage/gen-model/file_storage';
|
||||
import { booleanDelay } from '../../../../custom-operators';
|
||||
import { download } from './download';
|
||||
|
||||
@Injectable()
|
||||
export class FileContainerService {
|
||||
private getFileInfo$ = new Subject<string>();
|
||||
|
||||
fileData$: Observable<FileData | FileNotFound> = this.getFileInfo$.pipe(
|
||||
switchMap(fileID => this.fileStorageService.getFileData(fileID)),
|
||||
shareReplay(1)
|
||||
);
|
||||
|
||||
isLoading$ = this.fileData$.pipe(
|
||||
booleanDelay(),
|
||||
shareReplay(1)
|
||||
);
|
||||
|
||||
constructor(private fileStorageService: FileStorageService, private snackBar: MatSnackBar) {
|
||||
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.snackBar.open('File not found', 'OK');
|
||||
}
|
||||
},
|
||||
() => this.snackBar.open('Download error', 'OK')
|
||||
);
|
||||
}
|
||||
}
|
@ -0,0 +1,2 @@
|
||||
export * from './file-container.module';
|
||||
export * from './file-container.component';
|
@ -0,0 +1,3 @@
|
||||
.dsh-file-uploader:hover {
|
||||
cursor: pointer;
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
<div ngfSelect class="dsh-file-uploader" (filesChange)="startUploading($event)">
|
||||
<button mat-icon-button [disabled]="inProgress$ | async">
|
||||
<mat-icon>attach_file</mat-icon>
|
||||
</button>
|
||||
</div>
|
@ -0,0 +1,27 @@
|
||||
import { Component, EventEmitter, Output } from '@angular/core';
|
||||
|
||||
import { FileUploaderService } from './file-uploader.service';
|
||||
import { Modification } from '../../../../thrift-services/damsel/gen-model/claim_management';
|
||||
|
||||
@Component({
|
||||
selector: 'cc-file-uploader',
|
||||
templateUrl: 'file-uploader.component.html',
|
||||
styleUrls: ['file-uploader.component.css']
|
||||
})
|
||||
export class FileUploaderComponent {
|
||||
@Output()
|
||||
filesUploaded: EventEmitter<Modification[]> = new EventEmitter();
|
||||
|
||||
startUploading$ = this.fileUploaderService.startUploading$;
|
||||
inProgress$ = this.fileUploaderService.inProgress$;
|
||||
|
||||
constructor(private fileUploaderService: FileUploaderService) {
|
||||
this.fileUploaderService.filesUploaded$.subscribe(values =>
|
||||
this.filesUploaded.emit(values.map(v => this.fileUploaderService.createModification(v)))
|
||||
);
|
||||
}
|
||||
|
||||
startUploading(files: File[]) {
|
||||
this.startUploading$.next(files);
|
||||
}
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { FlexModule } from '@angular/flex-layout';
|
||||
import { ngfModule } from 'angular-file';
|
||||
|
||||
import { FileUploaderComponent } from './file-uploader.component';
|
||||
import { FileUploaderService } from './file-uploader.service';
|
||||
import { MatIconModule } from '@angular/material/icon';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
|
||||
@NgModule({
|
||||
imports: [FlexModule, ngfModule, CommonModule, MatIconModule, MatButtonModule],
|
||||
exports: [FileUploaderComponent],
|
||||
declarations: [FileUploaderComponent],
|
||||
providers: [FileUploaderService]
|
||||
})
|
||||
export class FileUploaderModule {}
|
@ -0,0 +1,92 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { MatSnackBar } from '@angular/material/snack-bar';
|
||||
import { forkJoin, merge, Observable, of, Subject } from 'rxjs';
|
||||
import { catchError, filter, map, shareReplay, switchMap } from 'rxjs/operators';
|
||||
import * as moment from 'moment';
|
||||
import { progress } from '@rbkmoney/partial-fetcher/dist/progress';
|
||||
|
||||
import { FileStorageService } from '../../../../thrift-services/file-storage/file-storage.service';
|
||||
import { NewFileResult } from '../../../../thrift-services/file-storage/gen-model/file_storage';
|
||||
import { Value } from '../../../../thrift-services/file-storage/gen-model/msgpack';
|
||||
import { Modification } from '../../../../thrift-services/damsel/gen-model/claim_management';
|
||||
|
||||
@Injectable()
|
||||
export class FileUploaderService {
|
||||
startUploading$ = new Subject<File[]>();
|
||||
|
||||
filesUploadingError$ = new Subject<null>();
|
||||
|
||||
filesUploaded$: Observable<string[]> = this.startUploading$.pipe(
|
||||
switchMap(files =>
|
||||
this.uploadFiles(files).pipe(
|
||||
catchError(() => {
|
||||
this.filesUploadingError$.next(null);
|
||||
return of([]);
|
||||
})
|
||||
)
|
||||
),
|
||||
filter(v => !!v.length),
|
||||
shareReplay(1)
|
||||
);
|
||||
|
||||
inProgress$: Observable<boolean> = progress(
|
||||
this.startUploading$,
|
||||
merge(this.filesUploaded$, this.filesUploadingError$)
|
||||
);
|
||||
|
||||
constructor(
|
||||
private fileStorageService: FileStorageService,
|
||||
private snackBar: MatSnackBar,
|
||||
private http: HttpClient
|
||||
) {
|
||||
this.filesUploadingError$.subscribe(() => this.snackBar.open('File uploading error', 'OK'));
|
||||
}
|
||||
|
||||
uploadFiles(files: File[]): Observable<string[]> {
|
||||
return forkJoin(
|
||||
files.map(file =>
|
||||
this.getUploadLink().pipe(
|
||||
switchMap(uploadData =>
|
||||
forkJoin(
|
||||
of(uploadData.file_data_id),
|
||||
this.uploadFileToUrl(file, uploadData.upload_url)
|
||||
)
|
||||
),
|
||||
map(([fileId]) => fileId)
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
createModification(id: string): Modification {
|
||||
return {
|
||||
claim_modification: {
|
||||
file_modification: {
|
||||
id,
|
||||
modification: {
|
||||
creation: {}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
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=${file.name}`,
|
||||
'Content-Type': ''
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
22
src/app/claim-mgt/claim/conversation/questionary.service.ts
Normal file
22
src/app/claim-mgt/claim/conversation/questionary.service.ts
Normal file
@ -0,0 +1,22 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { ConversationService } from './conversation.service';
|
||||
import { switchMap, pluck, map, publishReplay } from 'rxjs/operators';
|
||||
import { AnkService } from '../../../thrift-services/ank/ank.service';
|
||||
import { TimelineAction } from './to-timeline-info/model';
|
||||
import { ConnectableObservable } from 'rxjs';
|
||||
import { Questionary } from '../../../thrift-services/ank/gen-model/questionary_manager';
|
||||
|
||||
@Injectable()
|
||||
export class QuestionaryService {
|
||||
questionary$ = this.conversationService.timelineInfos$.pipe(
|
||||
map(timelineInfos => timelineInfos.find(i => i.action === TimelineAction.changesAdded)),
|
||||
pluck('modifications', 0, 'claim_modification', 'document_modification', 'id'),
|
||||
switchMap(id => this.ankService.get(id)),
|
||||
pluck('questionary'),
|
||||
publishReplay(1)
|
||||
) as ConnectableObservable<Questionary>;
|
||||
|
||||
constructor(private conversationService: ConversationService, private ankService: AnkService) {
|
||||
this.questionary$.connect();
|
||||
}
|
||||
}
|
@ -0,0 +1 @@
|
||||
export * from './questionary.component';
|
@ -0,0 +1 @@
|
||||
<mat-card> <mat-card-content> Questionary </mat-card-content> </mat-card>
|
@ -0,0 +1,3 @@
|
||||
mat-card-content {
|
||||
word-break: break-all;
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
import { Component, Input } from '@angular/core';
|
||||
|
||||
import { Questionary } from '../../../../thrift-services/ank/gen-model/questionary_manager';
|
||||
|
||||
@Component({
|
||||
selector: 'cc-questionary',
|
||||
templateUrl: 'questionary.component.html',
|
||||
styleUrls: ['questionary.component.scss']
|
||||
})
|
||||
export class QuestionaryComponent {
|
||||
@Input() questionary: Questionary;
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
<mat-card>
|
||||
<mat-card-content>
|
||||
{{
|
||||
statusModificationUnit.status.denied?.reason ||
|
||||
statusModificationUnit.status.revoked?.reason
|
||||
}}
|
||||
</mat-card-content>
|
||||
</mat-card>
|
@ -0,0 +1,10 @@
|
||||
import { Component, Input } from '@angular/core';
|
||||
import { StatusModificationUnit } from '../../../../thrift-services/damsel/gen-model/claim_management';
|
||||
|
||||
@Component({
|
||||
selector: 'cc-reason',
|
||||
templateUrl: 'reason.component.html'
|
||||
})
|
||||
export class ReasonComponent {
|
||||
@Input() statusModificationUnit: StatusModificationUnit;
|
||||
}
|
@ -0,0 +1 @@
|
||||
export * from './send-comment.component';
|
@ -0,0 +1,16 @@
|
||||
<form [formGroup]="form" fxLayout="row" fxLayoutGap="10px" fxLayoutAlign="space-between end">
|
||||
<mat-form-field fxFlex>
|
||||
<mat-label>Write a comment...</mat-label>
|
||||
<input formControlName="comment" matInput type="text" autocomplete="off" />
|
||||
</mat-form-field>
|
||||
<div class="send-comment-action">
|
||||
<button
|
||||
mat-icon-button
|
||||
color="accent"
|
||||
(click)="sendComment(form.value.comment)"
|
||||
[disabled]="(inProgress$ | async) || !form.valid"
|
||||
>
|
||||
<mat-icon>send</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
@ -0,0 +1,9 @@
|
||||
$cc-send-comment-action-padding: 10px 0 0 0;
|
||||
|
||||
.send-comment-action {
|
||||
padding: $cc-send-comment-action-padding;
|
||||
}
|
||||
|
||||
button {
|
||||
margin-bottom: 1.25em;
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
import { Component, Output, EventEmitter } from '@angular/core';
|
||||
import { FormGroup } from '@angular/forms';
|
||||
|
||||
import { SendCommentService } from './send-comment.service';
|
||||
import { Modification } from '../../../../thrift-services/damsel/gen-model/claim_management';
|
||||
|
||||
@Component({
|
||||
selector: 'cc-send-comment',
|
||||
templateUrl: 'send-comment.component.html',
|
||||
styleUrls: ['send-comment.component.scss'],
|
||||
providers: [SendCommentService]
|
||||
})
|
||||
export class SendCommentComponent {
|
||||
@Output() conversationSaved: EventEmitter<Modification[]> = new EventEmitter();
|
||||
|
||||
form: FormGroup = this.sendCommentService.form;
|
||||
inProgress$ = this.sendCommentService.inProgress$;
|
||||
|
||||
constructor(private sendCommentService: SendCommentService) {
|
||||
this.sendCommentService.conversationSaved$.subscribe(id =>
|
||||
this.conversationSaved.next([sendCommentService.createModification(id)])
|
||||
);
|
||||
this.inProgress$.subscribe(inProgress => {
|
||||
if (inProgress) {
|
||||
this.form.controls.comment.disable();
|
||||
} else {
|
||||
this.form.controls.comment.enable();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
sendComment(comment: string) {
|
||||
this.sendCommentService.sendComment(comment);
|
||||
}
|
||||
}
|
@ -0,0 +1,96 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { FormGroup, FormBuilder, Validators } from '@angular/forms';
|
||||
import { Subject, of, forkJoin, BehaviorSubject, Observable, merge } from 'rxjs';
|
||||
import { switchMap, filter, catchError, pluck, tap } from 'rxjs/operators';
|
||||
import * as uuid from 'uuid/v4';
|
||||
import get from 'lodash-es/get';
|
||||
import { progress } from '@rbkmoney/partial-fetcher/dist/progress';
|
||||
import { MatSnackBar } from '@angular/material/snack-bar';
|
||||
|
||||
import { ConversationId, User } from '../../../../thrift-services/messages/gen-model/messages';
|
||||
import { MessagesService } from '../../../../thrift-services/messages/messages.service';
|
||||
import { createSingleMessageConversationParams } from '../../../../thrift-services/messages/utils';
|
||||
import { KeycloakTokenInfoService } from '../../../../keycloak-token-info.service';
|
||||
import { Modification } from '../../../../thrift-services/damsel/gen-model/claim_management';
|
||||
|
||||
@Injectable()
|
||||
export class SendCommentService {
|
||||
private conversationId$: BehaviorSubject<ConversationId | null> = new BehaviorSubject(null);
|
||||
private error$: BehaviorSubject<any> = new BehaviorSubject({ hasError: false });
|
||||
private sendComment$: Subject<string> = new Subject();
|
||||
|
||||
form: FormGroup;
|
||||
conversationSaved$: Observable<ConversationId> = this.conversationId$.pipe(filter(id => !!id));
|
||||
errorCode$: Observable<string> = this.error$.pipe(pluck('code'));
|
||||
inProgress$: Observable<boolean> = progress(
|
||||
this.sendComment$,
|
||||
merge(this.conversationId$, this.error$)
|
||||
);
|
||||
|
||||
constructor(
|
||||
private fb: FormBuilder,
|
||||
private messagesService: MessagesService,
|
||||
private keycloakTokenInfoService: KeycloakTokenInfoService,
|
||||
private snackBar: MatSnackBar
|
||||
) {
|
||||
this.form = this.fb.group({
|
||||
comment: ['', [Validators.maxLength(1000)]]
|
||||
});
|
||||
|
||||
this.sendComment$
|
||||
.pipe(
|
||||
tap(() => this.error$.next({ hasError: false })),
|
||||
switchMap(text => {
|
||||
const { name, email, sub } = this.keycloakTokenInfoService.decodedUserToken;
|
||||
const user: User = { fullname: name, email, user_id: sub };
|
||||
const conversation_id = uuid();
|
||||
const conversation = createSingleMessageConversationParams(
|
||||
conversation_id,
|
||||
text,
|
||||
sub
|
||||
);
|
||||
return forkJoin(
|
||||
of(conversation_id),
|
||||
this.messagesService.saveConversations([conversation], user).pipe(
|
||||
catchError(ex => {
|
||||
console.error(ex);
|
||||
this.snackBar.open(
|
||||
`There was an error sending a comment: ${ex}`,
|
||||
'OK',
|
||||
{ duration: 5000 }
|
||||
);
|
||||
const error = { hasError: true, code: 'saveConversationsFailed' };
|
||||
this.error$.next(error);
|
||||
return of(error);
|
||||
})
|
||||
)
|
||||
);
|
||||
}),
|
||||
filter(([, res]) => get(res, ['hasError']) !== true)
|
||||
)
|
||||
.subscribe(([conversation_id]) => {
|
||||
this.conversationId$.next(conversation_id);
|
||||
this.form.reset();
|
||||
});
|
||||
}
|
||||
|
||||
sendComment(comment: string) {
|
||||
if (comment.length === 0) {
|
||||
return;
|
||||
}
|
||||
this.sendComment$.next(comment);
|
||||
}
|
||||
|
||||
createModification(id: ConversationId): Modification {
|
||||
return {
|
||||
claim_modification: {
|
||||
comment_modification: {
|
||||
id,
|
||||
modification: {
|
||||
creation: {}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
import { Conversation } from '../../../../thrift-services/messages/gen-model/messages';
|
||||
import { TimelineAction, TimelineItemInfo } from './model';
|
||||
|
||||
export const addCommentsToTimelineInfos = (
|
||||
conversations: Conversation[],
|
||||
infos: TimelineItemInfo[]
|
||||
): TimelineItemInfo[] =>
|
||||
infos.map(info => {
|
||||
if (info.action === TimelineAction.commentAdded) {
|
||||
return {
|
||||
...info,
|
||||
data: conversations
|
||||
? conversations.find(conversation => {
|
||||
return !!info.modifications.find(
|
||||
m =>
|
||||
m.claim_modification.comment_modification.id ===
|
||||
conversation.conversation_id
|
||||
);
|
||||
})
|
||||
: null
|
||||
};
|
||||
} else {
|
||||
return info;
|
||||
}
|
||||
});
|
@ -0,0 +1,41 @@
|
||||
import { TimelineAction } from './model';
|
||||
import {
|
||||
ClaimModification,
|
||||
StatusModificationUnit
|
||||
} from '../../../../thrift-services/damsel/gen-model/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}`);
|
||||
}
|
@ -0,0 +1,2 @@
|
||||
export * from './to-timeline-info';
|
||||
export * from './add-comments-to-timeline-info';
|
@ -0,0 +1,2 @@
|
||||
export * from './timeline-item-info';
|
||||
export * from './timeline-action';
|
@ -0,0 +1,10 @@
|
||||
export enum TimelineAction {
|
||||
changesAdded = 'changesAdded',
|
||||
filesAdded = 'filesAdded',
|
||||
commentAdded = 'commentAdded',
|
||||
statusReview = 'statusReview',
|
||||
statusPending = 'statusPending',
|
||||
statusDenied = 'statusDenied',
|
||||
statusRevoked = 'statusRevoked',
|
||||
statusAccepted = 'statusAccepted'
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
import { TimelineAction } from './timeline-action';
|
||||
import {
|
||||
Modification,
|
||||
UserInfo
|
||||
} from '../../../../../thrift-services/damsel/gen-model/claim_management';
|
||||
import { Conversation } from '../../../../../thrift-services/messages/gen-model/messages';
|
||||
|
||||
export interface TimelineItemInfo {
|
||||
action: TimelineAction;
|
||||
user_info: UserInfo;
|
||||
created_at: string;
|
||||
modifications: Modification[];
|
||||
data?: Conversation;
|
||||
}
|
@ -0,0 +1,68 @@
|
||||
import {
|
||||
ClaimModification,
|
||||
Modification,
|
||||
ModificationUnit
|
||||
} from '../../../../thrift-services/damsel/gen-model/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 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 = [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, []);
|
||||
};
|
56
src/app/claim-mgt/claim/details/details.component.html
Normal file
56
src/app/claim-mgt/claim/details/details.component.html
Normal file
@ -0,0 +1,56 @@
|
||||
<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">Revision:</label>
|
||||
<div>{{ claim.revision }}</div>
|
||||
</div>
|
||||
<div fxLayout="row" fxLayout.xs="column">
|
||||
<label fxFlex="20">Status:</label>
|
||||
<div>{{ claim.status | ccClaimStatus }}</div>
|
||||
</div>
|
||||
<div
|
||||
fxLayout="row"
|
||||
fxLayout.xs="column"
|
||||
*ngIf="claim.status.denied || claim.status.revoked"
|
||||
>
|
||||
<label fxFlex="20">Reason:</label>
|
||||
<div>{{ claim.status.revoked?.reason || claim.status.denied?.reason }}</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-actions fxLayout="row" fxLayoutAlign="space-between stretch">
|
||||
<div fxLayout="row" fxLayout.xs="column">
|
||||
<button mat-button [disabled]="" (click)="addModification()">ADD MODIFICATION</button>
|
||||
</div>
|
||||
<div fxLayout="row" fxLayout.xs="column">
|
||||
<button
|
||||
mat-raised-button
|
||||
color="primary"
|
||||
(click)="editStatus()"
|
||||
[disabled]="!canChangeStatus()"
|
||||
>
|
||||
CHANGE STATUS
|
||||
</button>
|
||||
</div>
|
||||
</mat-card-actions>
|
||||
</mat-card>
|
56
src/app/claim-mgt/claim/details/details.component.ts
Normal file
56
src/app/claim-mgt/claim/details/details.component.ts
Normal file
@ -0,0 +1,56 @@
|
||||
import { Component, Input } from '@angular/core';
|
||||
import { MatDialog } from '@angular/material/dialog';
|
||||
import { MatBottomSheet } from '@angular/material/bottom-sheet';
|
||||
import { filter } from 'rxjs/operators';
|
||||
|
||||
import { Claim } from '../../../thrift-services/damsel/gen-model/claim_management';
|
||||
import { StatusChangerComponent } from '../status-changer/status-changer.component';
|
||||
import { getAvailableClaimStatuses } from '../status-changer/get-available-claim-statuses';
|
||||
import { ClaimService } from '../claim.service';
|
||||
import { UnitActionsComponent } from '../party-modification-creator/unit-actions/unit-actions.component';
|
||||
|
||||
@Component({
|
||||
selector: 'cc-claim-details',
|
||||
templateUrl: 'details.component.html'
|
||||
})
|
||||
export class DetailsComponent {
|
||||
@Input() claim: Claim;
|
||||
|
||||
constructor(
|
||||
private dialog: MatDialog,
|
||||
private claimService: ClaimService,
|
||||
private bottomSheet: MatBottomSheet
|
||||
) {}
|
||||
|
||||
editStatus() {
|
||||
this.dialog
|
||||
.open(StatusChangerComponent, {
|
||||
width: '500px',
|
||||
disableClose: true,
|
||||
data: {
|
||||
partyID: this.claim.party_id,
|
||||
claimID: this.claim.id,
|
||||
claimStatus: this.claim.status
|
||||
}
|
||||
})
|
||||
.afterClosed()
|
||||
.pipe(filter(r => r))
|
||||
.subscribe(_ => {
|
||||
this.claimService.getClaim(this.claim.party_id, this.claim.id);
|
||||
});
|
||||
}
|
||||
|
||||
canChangeStatus(): boolean {
|
||||
return getAvailableClaimStatuses(this.claim.status).length > 0;
|
||||
}
|
||||
|
||||
addModification() {
|
||||
this.bottomSheet.open(UnitActionsComponent, {
|
||||
data: {
|
||||
partyID: this.claim.party_id,
|
||||
claimID: this.claim.id,
|
||||
type: 'allActions'
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
1
src/app/claim-mgt/claim/index.ts
Normal file
1
src/app/claim-mgt/claim/index.ts
Normal file
@ -0,0 +1 @@
|
||||
export * from './claim.module';
|
@ -0,0 +1,66 @@
|
||||
import { Pipe, PipeTransform } from '@angular/core';
|
||||
import { ShopModificationName } from './shop-modification-name';
|
||||
import { ContractModificationName } from './contract-modification-name';
|
||||
import { ModificationGroupType } from '../../../claim/model';
|
||||
|
||||
@Pipe({
|
||||
name: 'ccContainerName'
|
||||
})
|
||||
export class ContainerNamePipe implements PipeTransform {
|
||||
transform(value: any, ...args: any[]): any {
|
||||
if (args.length < 1) {
|
||||
return value;
|
||||
}
|
||||
const type = args[0] as ModificationGroupType;
|
||||
switch (type) {
|
||||
case ModificationGroupType.ShopUnitContainer:
|
||||
return this.transformShopModification(value);
|
||||
case ModificationGroupType.ContractUnitContainer:
|
||||
return this.transformContractModificationName(value);
|
||||
default:
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
private transformShopModification(value: ShopModificationName): string {
|
||||
switch (value) {
|
||||
case ShopModificationName.creation:
|
||||
return 'Shop creation';
|
||||
case ShopModificationName.categoryModification:
|
||||
return 'Shop category modification';
|
||||
case ShopModificationName.detailsModification:
|
||||
return 'Shop details modification';
|
||||
case ShopModificationName.contractModification:
|
||||
return 'Shop contract modification';
|
||||
case ShopModificationName.payoutToolModification:
|
||||
return 'Shop payout tool modification';
|
||||
case ShopModificationName.locationModification:
|
||||
return 'Shop location modification';
|
||||
case ShopModificationName.shopAccountCreation:
|
||||
return 'Shop account creation';
|
||||
case ShopModificationName.payoutScheduleModification:
|
||||
return 'Shop schedule modification';
|
||||
default:
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
private transformContractModificationName(value: ContractModificationName): string {
|
||||
switch (value) {
|
||||
case ContractModificationName.creation:
|
||||
return 'Contract creation';
|
||||
case ContractModificationName.termination:
|
||||
return 'Contract termination';
|
||||
case ContractModificationName.adjustmentModification:
|
||||
return 'Contract adjustment modification';
|
||||
case ContractModificationName.payoutToolModification:
|
||||
return 'Contract payout tool modification';
|
||||
case ContractModificationName.legalAgreementBinding:
|
||||
return 'Contract legal agreement binding';
|
||||
case ContractModificationName.reportPreferencesModification:
|
||||
return 'Contract report preferences modification';
|
||||
default:
|
||||
return value;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
export enum ContractModificationName {
|
||||
creation = 'creation',
|
||||
termination = 'termination',
|
||||
adjustmentModification = 'adjustment_modification',
|
||||
payoutToolModification = 'payout_tool_modification',
|
||||
legalAgreementBinding = 'legal_agreement_binding',
|
||||
reportPreferencesModification = 'report_preferences_modification',
|
||||
contractorModification = 'contractor_modification',
|
||||
unknown = 'unknown'
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
<div class="mat-dialog-title">
|
||||
{{ action.name | ccContainerName: getContainerType(action.type) }}
|
||||
</div>
|
||||
<mat-dialog-content>
|
||||
<cc-party-modification-creation
|
||||
[action]="action"
|
||||
(valueChanges)="valueChanges($event)"
|
||||
(statusChanges)="statusChanges($event)"
|
||||
>
|
||||
</cc-party-modification-creation>
|
||||
</mat-dialog-content>
|
||||
<mat-dialog-actions *ngIf="initialized">
|
||||
<button mat-button [disabled]="isLoading || !valid" color="primary" (click)="apply()">
|
||||
APPLY
|
||||
</button>
|
||||
<button [disabled]="isLoading" mat-button [mat-dialog-close]="false">CANCEL</button>
|
||||
<mat-progress-bar mode="indeterminate" *ngIf="isLoading"></mat-progress-bar>
|
||||
</mat-dialog-actions>
|
@ -0,0 +1,88 @@
|
||||
import { Component, Inject, OnInit } from '@angular/core';
|
||||
import { MAT_DIALOG_DATA } from '@angular/material';
|
||||
import { MatDialogRef } from '@angular/material/dialog';
|
||||
|
||||
import { ActionType, ModificationAction } from './modification-action';
|
||||
import {
|
||||
ClaimID,
|
||||
PartyModification
|
||||
} from '../../../thrift-services/damsel/gen-model/claim_management';
|
||||
import { ModificationGroupType } from '../../../claim/model';
|
||||
import { ClaimManagementService } from '../../../thrift-services/damsel/claim-management.service';
|
||||
import { ClaimService } from '../claim.service';
|
||||
|
||||
export interface CreateModificationData {
|
||||
action: ModificationAction;
|
||||
claimID: ClaimID;
|
||||
partyID: string;
|
||||
}
|
||||
|
||||
@Component({
|
||||
templateUrl: 'create-modification.component.html'
|
||||
})
|
||||
export class CreateModificationComponent implements OnInit {
|
||||
isLoading = false;
|
||||
valid = false;
|
||||
initialized = false;
|
||||
|
||||
values: PartyModification;
|
||||
|
||||
action: ModificationAction;
|
||||
|
||||
constructor(
|
||||
private dialogRef: MatDialogRef<CreateModificationComponent>,
|
||||
@Inject(MAT_DIALOG_DATA) public data: CreateModificationData,
|
||||
private claimManagementService: ClaimManagementService,
|
||||
private claimService: ClaimService
|
||||
) {}
|
||||
|
||||
ngOnInit() {
|
||||
this.action = this.data.action;
|
||||
this.initialized = true;
|
||||
}
|
||||
|
||||
valueChanges(e: any) {
|
||||
this.values = e;
|
||||
}
|
||||
|
||||
statusChanges(status: string) {
|
||||
this.valid = status === 'VALID';
|
||||
}
|
||||
|
||||
apply() {
|
||||
switch (this.data.action.type) {
|
||||
case ActionType.shopAction:
|
||||
case ActionType.contractAction:
|
||||
this.addChange();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
getContainerType(type: ActionType): string {
|
||||
switch (type) {
|
||||
case ActionType.shopAction:
|
||||
return ModificationGroupType.ShopUnitContainer;
|
||||
case ActionType.contractAction:
|
||||
return ModificationGroupType.ContractUnitContainer;
|
||||
}
|
||||
}
|
||||
|
||||
private addChange() {
|
||||
this.isLoading = true;
|
||||
this.claimManagementService
|
||||
.updateClaim(this.data.partyID, this.data.claimID, [
|
||||
{ party_modification: this.values }
|
||||
])
|
||||
.subscribe(
|
||||
_ => {
|
||||
this.isLoading = false;
|
||||
this.claimService.getClaim(this.data.partyID, this.data.claimID);
|
||||
this.dialogRef.close(true);
|
||||
},
|
||||
e => {
|
||||
this.isLoading = false;
|
||||
console.error(e);
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
<form [formGroup]="form">
|
||||
<cc-business-schedule-selector
|
||||
(idChange)="scheduleIdChange($event)"
|
||||
[initialValue]="initialValue?.id.valueOf()"
|
||||
></cc-business-schedule-selector>
|
||||
</form>
|
@ -0,0 +1,28 @@
|
||||
import { Component, Input, OnInit } from '@angular/core';
|
||||
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
|
||||
import get from 'lodash-es/get';
|
||||
import { BusinessScheduleRef } from '../../../../../thrift-services/damsel/gen-model/domain';
|
||||
|
||||
@Component({
|
||||
selector: 'cc-business-schedule-ref',
|
||||
templateUrl: 'business-schedule-ref.component.html'
|
||||
})
|
||||
export class BusinessScheduleRefComponent implements OnInit {
|
||||
@Input()
|
||||
form: FormGroup;
|
||||
|
||||
@Input()
|
||||
initialValue: BusinessScheduleRef;
|
||||
|
||||
constructor(private fb: FormBuilder) {}
|
||||
|
||||
ngOnInit() {
|
||||
const id = get(this, 'initialValue.id', '');
|
||||
this.form.registerControl('id', this.fb.control(id, Validators.required));
|
||||
this.form.updateValueAndValidity();
|
||||
}
|
||||
|
||||
scheduleIdChange(id: number) {
|
||||
this.form.controls.id.setValue(id);
|
||||
}
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
<div fxLayout="column">
|
||||
<mat-form-field>
|
||||
<mat-select
|
||||
placeholder="Select schedule"
|
||||
[disabled]="isLoading || hasError"
|
||||
(selectionChange)="selectionChange($event)"
|
||||
[value]="initialValue"
|
||||
>
|
||||
<mat-option *ngFor="let schedule of (schedules$ | async)" [value]="schedule.ref.id">
|
||||
{{ schedule.ref.id }} {{ schedule.data.name }}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
<mat-progress-bar *ngIf="isLoading" mode="indeterminate"></mat-progress-bar>
|
||||
</div>
|
@ -0,0 +1,45 @@
|
||||
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
|
||||
import { MatSelectChange, MatSnackBar } from '@angular/material';
|
||||
import { tap } from 'rxjs/internal/operators';
|
||||
import { Observable } from 'rxjs';
|
||||
import { BusinessScheduleObject } from '../../../../../../thrift-services/damsel/gen-model/domain';
|
||||
import { DomainTypedManager } from '../../../../../../thrift-services';
|
||||
|
||||
@Component({
|
||||
selector: 'cc-business-schedule-selector',
|
||||
templateUrl: 'business-schedule-selector.component.html'
|
||||
})
|
||||
export class BusinessScheduleSelectorComponent implements OnInit {
|
||||
@Input()
|
||||
initialValue: string;
|
||||
|
||||
@Output()
|
||||
idChange = new EventEmitter<number>();
|
||||
|
||||
schedules$: Observable<BusinessScheduleObject[]>;
|
||||
|
||||
isLoading = true;
|
||||
|
||||
hasError = false;
|
||||
|
||||
constructor(private domainManager: DomainTypedManager, private snackBar: MatSnackBar) {}
|
||||
|
||||
selectionChange(change: MatSelectChange) {
|
||||
this.idChange.emit(change.value);
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.schedules$ = this.domainManager.getBusinessScheduleObjects().pipe(
|
||||
tap(
|
||||
() => {
|
||||
this.isLoading = false;
|
||||
},
|
||||
() => {
|
||||
this.isLoading = false;
|
||||
this.hasError = true;
|
||||
this.snackBar.open('An error occurred while business schedule receiving', 'OK');
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
<form [formGroup]="form" fxLayout="column" fxLayoutGap="15px">
|
||||
<mat-form-field fxFlex>
|
||||
<input matInput placeholder="Adjustment ID" formControlName="adjustment_id" required />
|
||||
</mat-form-field>
|
||||
<div><button (click)="generate()" mat-stroked-button>GENERATE NEW VALUE</button></div>
|
||||
<cc-adjustment-modification
|
||||
[form]="form.get('modification')"
|
||||
[initialValue]="initialValue?.modification"
|
||||
>
|
||||
</cc-adjustment-modification>
|
||||
</form>
|
@ -0,0 +1,33 @@
|
||||
import { Component, Input, OnInit } from '@angular/core';
|
||||
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
|
||||
import * as uuid from 'uuid/v4';
|
||||
import get from 'lodash-es/get';
|
||||
import { ContractAdjustmentModificationUnit } from '../../../../../../thrift-services/damsel/gen-model/claim_management';
|
||||
|
||||
@Component({
|
||||
selector: 'cc-adjustment-modification-unit',
|
||||
templateUrl: 'adjustment-modification-unit.component.html'
|
||||
})
|
||||
export class AdjustmentModificationUnitComponent implements OnInit {
|
||||
@Input()
|
||||
form: FormGroup;
|
||||
|
||||
@Input()
|
||||
initialValue: ContractAdjustmentModificationUnit;
|
||||
|
||||
constructor(private fb: FormBuilder) {}
|
||||
|
||||
ngOnInit() {
|
||||
const adjustmentId = get(this, 'initialValue.adjustment_id', '');
|
||||
this.form.registerControl(
|
||||
'adjustment_id',
|
||||
this.fb.control(adjustmentId, Validators.required)
|
||||
);
|
||||
this.form.registerControl('modification', this.fb.group({}));
|
||||
this.form.updateValueAndValidity();
|
||||
}
|
||||
|
||||
generate() {
|
||||
this.form.patchValue({ adjustment_id: uuid() });
|
||||
}
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
<div fxLayout="column">
|
||||
<cc-contract-adjustment-params
|
||||
[form]="form.get('creation')"
|
||||
[initialValue]="initialValue?.creation"
|
||||
>
|
||||
</cc-contract-adjustment-params>
|
||||
</div>
|
@ -0,0 +1,22 @@
|
||||
import { Component, Input, OnInit } from '@angular/core';
|
||||
import { FormBuilder, FormGroup } from '@angular/forms';
|
||||
import { ContractAdjustmentModification } from '../../../../../../thrift-services/damsel/gen-model/claim_management';
|
||||
|
||||
@Component({
|
||||
selector: 'cc-adjustment-modification',
|
||||
templateUrl: 'adjustment-modification.component.html'
|
||||
})
|
||||
export class AdjustmentModificationComponent implements OnInit {
|
||||
@Input()
|
||||
form: FormGroup;
|
||||
|
||||
@Input()
|
||||
initialValue: ContractAdjustmentModification;
|
||||
|
||||
constructor(private fb: FormBuilder) {}
|
||||
|
||||
ngOnInit() {
|
||||
this.form.registerControl('creation', this.fb.group({}));
|
||||
this.form.updateValueAndValidity();
|
||||
}
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
<form [formGroup]="form" fxLayout="column" fxLayoutGap="5px">
|
||||
<cc-contract-template-ref
|
||||
[form]="form.get('template')"
|
||||
[required]="true"
|
||||
[initialValue]="initialValue?.template"
|
||||
>
|
||||
</cc-contract-template-ref>
|
||||
</form>
|
@ -0,0 +1,22 @@
|
||||
import { Component, Input, OnInit } from '@angular/core';
|
||||
import { FormBuilder, FormGroup } from '@angular/forms';
|
||||
import { ContractAdjustmentParams } from '../../../../../../thrift-services/damsel/gen-model/claim_management';
|
||||
|
||||
@Component({
|
||||
selector: 'cc-contract-adjustment-params',
|
||||
templateUrl: 'adjustment-params.component.html'
|
||||
})
|
||||
export class AdjustmentParamsComponent implements OnInit {
|
||||
@Input()
|
||||
form: FormGroup;
|
||||
|
||||
@Input()
|
||||
initialValue: ContractAdjustmentParams;
|
||||
|
||||
constructor(private fb: FormBuilder) {}
|
||||
|
||||
ngOnInit() {
|
||||
this.form.registerControl('template', this.fb.group({}));
|
||||
this.form.updateValueAndValidity();
|
||||
}
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
<form *ngIf="form" [formGroup]="form" fxLayout="column" fxLayoutGap="5px">
|
||||
<!--<mat-form-field fxFlex>-->
|
||||
<!--<input matInput-->
|
||||
<!--placeholder="Contractor ID"-->
|
||||
<!--formControlName="contractorId"-->
|
||||
<!--required>-->
|
||||
<!--</mat-form-field>-->
|
||||
<mat-checkbox [checked]="showTemplate" (change)="toggleCheckbox($event.checked, 'template')"
|
||||
>Template</mat-checkbox
|
||||
>
|
||||
<cc-contract-template-ref
|
||||
*ngIf="form.get('template')"
|
||||
[form]="form.get('template')"
|
||||
[initialValue]="initialValue?.template"
|
||||
>
|
||||
</cc-contract-template-ref>
|
||||
<mat-checkbox
|
||||
[checked]="showPaymentInstitution"
|
||||
(change)="toggleCheckbox($event.checked, 'payment_institution')"
|
||||
>Payment institution</mat-checkbox
|
||||
>
|
||||
<cc-payment-institution-ref
|
||||
*ngIf="form.get('payment_institution')"
|
||||
[form]="form.get('payment_institution')"
|
||||
[initialValue]="initialValue?.payment_institution"
|
||||
>
|
||||
</cc-payment-institution-ref>
|
||||
<!-- <cc-nested-form-wrapper caption="contractor">-->
|
||||
<!-- <cc-contractor-->
|
||||
<!-- fxFlex-->
|
||||
<!-- [form]="form.get('contractor')"-->
|
||||
<!-- [initialValue]="initialValue?.contractor"-->
|
||||
<!-- >-->
|
||||
<!-- </cc-contractor>-->
|
||||
<!-- </cc-nested-form-wrapper>-->
|
||||
</form>
|
@ -0,0 +1,49 @@
|
||||
import { Component, Input, OnInit } from '@angular/core';
|
||||
import { FormBuilder, FormGroup } from '@angular/forms';
|
||||
import { get } from 'lodash-es';
|
||||
import { ContractParams } from '../../../../../../thrift-services/damsel/gen-model/claim_management';
|
||||
|
||||
@Component({
|
||||
selector: 'cc-contract-params',
|
||||
templateUrl: 'contract-params.component.html'
|
||||
})
|
||||
export class ContractParamsComponent implements OnInit {
|
||||
@Input()
|
||||
form: FormGroup;
|
||||
|
||||
@Input()
|
||||
initialValue: ContractParams;
|
||||
|
||||
showTemplate = false;
|
||||
|
||||
showPaymentInstitution = false;
|
||||
|
||||
constructor(private fb: FormBuilder) {}
|
||||
|
||||
ngOnInit() {
|
||||
this.form.registerControl('contractor', this.fb.group({}));
|
||||
this.toggleTemplate();
|
||||
this.togglePaymentInstitution();
|
||||
this.form.updateValueAndValidity();
|
||||
}
|
||||
|
||||
toggleCheckbox(show: boolean, controlName: string, data: object = {}) {
|
||||
if (show) {
|
||||
this.form.registerControl(controlName, this.fb.group(data || {}));
|
||||
} else {
|
||||
this.form.removeControl(controlName);
|
||||
}
|
||||
}
|
||||
|
||||
toggleTemplate() {
|
||||
const template = get(this, 'initialValue.template', null);
|
||||
this.showTemplate = template !== null;
|
||||
this.toggleCheckbox(this.showTemplate, 'template', template);
|
||||
}
|
||||
|
||||
togglePaymentInstitution() {
|
||||
const paymentInstitution = get(this, 'initialValue.payment_institution', null);
|
||||
this.showPaymentInstitution = paymentInstitution !== null;
|
||||
this.toggleCheckbox(this.showPaymentInstitution, 'payment_institution', paymentInstitution);
|
||||
}
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
<form [formGroup]="form" fxLayout="column">
|
||||
<mat-form-field fxFlex>
|
||||
<mat-select placeholder="Select contract template" formControlName="id" required>
|
||||
<mat-option
|
||||
*ngFor="let contract of (contracts$ | async)"
|
||||
[value]="contract.id"
|
||||
required
|
||||
>
|
||||
{{ contract.id }} {{ contract.name }}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
<mat-progress-bar *ngIf="isLoading" mode="indeterminate"></mat-progress-bar>
|
||||
</form>
|
@ -0,0 +1,66 @@
|
||||
import { Component, Input, OnInit } from '@angular/core';
|
||||
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
|
||||
import { MatSnackBar } from '@angular/material';
|
||||
import { Observable } from 'rxjs';
|
||||
import { tap, map } from 'rxjs/internal/operators';
|
||||
import sortBy from 'lodash-es/sortBy';
|
||||
import get from 'lodash-es/get';
|
||||
import {
|
||||
ContractTemplate,
|
||||
ContractTemplateRef
|
||||
} from '../../../../../../thrift-services/damsel/gen-model/domain';
|
||||
import { ContractService } from './contract.service';
|
||||
|
||||
@Component({
|
||||
selector: 'cc-contract-template-ref',
|
||||
templateUrl: 'contract-template-ref.component.html',
|
||||
providers: [ContractService]
|
||||
})
|
||||
export class ContractTemplateRefComponent implements OnInit {
|
||||
@Input()
|
||||
form: FormGroup;
|
||||
|
||||
@Input()
|
||||
required: boolean;
|
||||
|
||||
@Input()
|
||||
initialValue: ContractTemplateRef;
|
||||
|
||||
contracts$: Observable<ContractTemplate[]>;
|
||||
|
||||
isLoading = true;
|
||||
|
||||
constructor(
|
||||
private fb: FormBuilder,
|
||||
private contractService: ContractService,
|
||||
private snackBar: MatSnackBar
|
||||
) {}
|
||||
|
||||
ngOnInit() {
|
||||
const templateId = get(this, 'initialValue.id', '');
|
||||
this.form.registerControl(
|
||||
'id',
|
||||
this.fb.control(
|
||||
{
|
||||
value: templateId,
|
||||
disabled: templateId.length === 0
|
||||
},
|
||||
this.required ? Validators.required : null
|
||||
)
|
||||
);
|
||||
this.form.updateValueAndValidity();
|
||||
this.contracts$ = this.contractService.getContractTemplates().pipe(
|
||||
map(contracts => sortBy(contracts, 'id')),
|
||||
tap(
|
||||
() => {
|
||||
this.form.controls.id.enable();
|
||||
this.isLoading = false;
|
||||
},
|
||||
() => {
|
||||
this.isLoading = false;
|
||||
this.snackBar.open('An error occurred while contract template receiving', 'OK');
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { Observable } from 'rxjs';
|
||||
import { ConfigService } from '../../../../../../core/config.service';
|
||||
import { ContractTemplate } from '../../../../../../thrift-services/damsel/gen-model/domain';
|
||||
|
||||
@Injectable()
|
||||
export class ContractService {
|
||||
private readonly papiEndpoint = this.configService.config.papiEndpoint;
|
||||
|
||||
constructor(private http: HttpClient, private configService: ConfigService) {}
|
||||
|
||||
getContractTemplates(): Observable<ContractTemplate[]> {
|
||||
return this.http.get<ContractTemplate[]>(`${this.papiEndpoint}/dmt/contract/templates`);
|
||||
}
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
<form [formGroup]="form" fxLayout="column" fxLayoutGap="5px">
|
||||
<mat-form-field fxFlex>
|
||||
<input matInput placeholder="Contractor ID" formControlName="modification" required />
|
||||
</mat-form-field>
|
||||
</form>
|
@ -0,0 +1,18 @@
|
||||
import { Component, Input, OnInit } from '@angular/core';
|
||||
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
|
||||
|
||||
@Component({
|
||||
selector: 'cc-contractor-id',
|
||||
templateUrl: 'contractor-id.component.html'
|
||||
})
|
||||
export class ContractorIdComponent implements OnInit {
|
||||
@Input()
|
||||
form: FormGroup;
|
||||
|
||||
constructor(private fb: FormBuilder) {}
|
||||
|
||||
ngOnInit() {
|
||||
this.form.registerControl('modification', this.fb.control('', Validators.required));
|
||||
this.form.updateValueAndValidity();
|
||||
}
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
<form *ngIf="form" [formGroup]="form" fxLayout="column" fxLayoutGap="5px">
|
||||
<cc-legal-entity [form]="form.get('legal_entity')" [initialValue]="initialValue?.legal_entity">
|
||||
</cc-legal-entity>
|
||||
</form>
|
@ -0,0 +1,22 @@
|
||||
import { Component, Input, OnInit } from '@angular/core';
|
||||
import { FormBuilder, FormGroup } from '@angular/forms';
|
||||
import { Contractor } from '../../../../../../thrift-services/damsel/gen-model/domain';
|
||||
|
||||
@Component({
|
||||
selector: 'cc-contractor',
|
||||
templateUrl: 'contractor.component.html'
|
||||
})
|
||||
export class ContractorComponent implements OnInit {
|
||||
@Input()
|
||||
form: FormGroup;
|
||||
|
||||
@Input()
|
||||
initialValue: Contractor;
|
||||
|
||||
constructor(private fb: FormBuilder) {}
|
||||
|
||||
ngOnInit() {
|
||||
this.form.registerControl('legal_entity', this.fb.group({}));
|
||||
this.form.updateValueAndValidity();
|
||||
}
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
<form [formGroup]="form" fxLayout="column" fxLayoutGap="5px">
|
||||
<mat-form-field fxFlex="50">
|
||||
<input
|
||||
matInput
|
||||
placeholder="Legal agreement ID"
|
||||
formControlName="legal_agreement_id"
|
||||
required
|
||||
/>
|
||||
</mat-form-field>
|
||||
<mat-form-field fxFlex="50">
|
||||
<input
|
||||
matInput
|
||||
[matDatepicker]="signedAtDatepicker"
|
||||
placeholder="Signed at"
|
||||
formControlName="signed_at"
|
||||
required
|
||||
/>
|
||||
<mat-datepicker-toggle matSuffix [for]="signedAtDatepicker"></mat-datepicker-toggle>
|
||||
<mat-datepicker #signedAtDatepicker></mat-datepicker>
|
||||
</mat-form-field>
|
||||
<mat-form-field fxFlex="50">
|
||||
<input
|
||||
matInput
|
||||
[matDatepicker]="validUntilDatepicker"
|
||||
placeholder="Valid until"
|
||||
formControlName="valid_until"
|
||||
/>
|
||||
<mat-datepicker-toggle matSuffix [for]="validUntilDatepicker"></mat-datepicker-toggle>
|
||||
<mat-datepicker #validUntilDatepicker></mat-datepicker>
|
||||
</mat-form-field>
|
||||
</form>
|
@ -0,0 +1,31 @@
|
||||
import { Component, Input, OnInit } from '@angular/core';
|
||||
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
|
||||
import get from 'lodash-es/get';
|
||||
import { LegalAgreement } from '../../../../../../thrift-services/damsel/gen-model/domain';
|
||||
|
||||
@Component({
|
||||
selector: 'cc-legal-agreement-binding',
|
||||
templateUrl: 'legal-agreement-binding.component.html'
|
||||
})
|
||||
export class LegalAgreementBindingComponent implements OnInit {
|
||||
@Input()
|
||||
form: FormGroup;
|
||||
|
||||
@Input()
|
||||
initialValue: LegalAgreement;
|
||||
|
||||
constructor(private fb: FormBuilder) {}
|
||||
|
||||
ngOnInit() {
|
||||
const legalAgreementId = get(this, 'initialValue.legal_agreement_id', '');
|
||||
const signedAt = get(this, 'initialValue.signed_at', '');
|
||||
const validUntil = get(this, 'initialValue.valid_until', '');
|
||||
this.form.registerControl(
|
||||
'legal_agreement_id',
|
||||
this.fb.control(legalAgreementId, Validators.required)
|
||||
);
|
||||
this.form.registerControl('signed_at', this.fb.control(signedAt, Validators.required));
|
||||
this.form.registerControl('valid_until', this.fb.control(validUntil));
|
||||
this.form.updateValueAndValidity();
|
||||
}
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
<form [formGroup]="form">
|
||||
<div fxLayout="column">
|
||||
<mat-form-field fxFlex>
|
||||
<input matInput placeholder="Legal name" formControlName="legal_name" required />
|
||||
</mat-form-field>
|
||||
<mat-form-field fxFlex>
|
||||
<input matInput placeholder="Trading name" formControlName="trading_name" />
|
||||
</mat-form-field>
|
||||
<mat-form-field fxFlex>
|
||||
<input
|
||||
matInput
|
||||
placeholder="Registered address"
|
||||
formControlName="registered_address"
|
||||
required
|
||||
/>
|
||||
</mat-form-field>
|
||||
<mat-form-field fxFlex>
|
||||
<input matInput placeholder="Actual address" formControlName="actual_address" />
|
||||
</mat-form-field>
|
||||
<mat-form-field fxFlex>
|
||||
<input matInput placeholder="Registered number" formControlName="registered_number" />
|
||||
</mat-form-field>
|
||||
</div>
|
||||
</form>
|
@ -0,0 +1,27 @@
|
||||
import { Component, Input, OnInit } from '@angular/core';
|
||||
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
|
||||
import { InternationalLegalEntity } from '../../../../../../../thrift-services/damsel/gen-model/domain';
|
||||
|
||||
@Component({
|
||||
selector: 'cc-international-legal-entity',
|
||||
templateUrl: 'international-legal-entity.component.html'
|
||||
})
|
||||
export class InternationalLegalEntityComponent implements OnInit {
|
||||
@Input()
|
||||
form: FormGroup;
|
||||
|
||||
@Input()
|
||||
initialValue: InternationalLegalEntity;
|
||||
|
||||
constructor(private fb: FormBuilder) {}
|
||||
|
||||
ngOnInit() {
|
||||
this.form.registerControl('legal_name', this.fb.control('', Validators.required));
|
||||
this.form.registerControl('registered_address', this.fb.control('', Validators.required));
|
||||
|
||||
this.form.registerControl('trading_name', this.fb.control(''));
|
||||
this.form.registerControl('actual_address', this.fb.control(''));
|
||||
this.form.registerControl('registered_number', this.fb.control(''));
|
||||
this.form.updateValueAndValidity();
|
||||
}
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
<cc-form-wrapper name="Legal entity">
|
||||
<div fxLayout="column">
|
||||
<mat-form-field>
|
||||
<mat-select
|
||||
placeholder="Legal entity type"
|
||||
[(value)]="selected"
|
||||
(selectionChange)="select()"
|
||||
>
|
||||
<mat-option *ngFor="let type of types" [value]="type">{{ type }}</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
<cc-russian-legal-entity
|
||||
*ngIf="selected === t.russian_legal_entity"
|
||||
[form]="form.get(t.russian_legal_entity)"
|
||||
[initialValue]="initialValue?.russian_legal_entity"
|
||||
>
|
||||
</cc-russian-legal-entity>
|
||||
<cc-international-legal-entity
|
||||
*ngIf="selected === t.international_legal_entity"
|
||||
[form]="form.get(t.international_legal_entity)"
|
||||
[initialValue]="initialValue?.international_legal_entity"
|
||||
>
|
||||
</cc-international-legal-entity>
|
||||
</div>
|
||||
</cc-form-wrapper>
|
@ -0,0 +1,56 @@
|
||||
import { Component, Input, OnInit } from '@angular/core';
|
||||
import { FormBuilder, FormGroup } from '@angular/forms';
|
||||
import get from 'lodash-es/get';
|
||||
import { LegalEntity } from '../../../../../../thrift-services/damsel/gen-model/domain';
|
||||
|
||||
enum Type {
|
||||
russian_legal_entity = 'russian_legal_entity',
|
||||
international_legal_entity = 'international_legal_entity'
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'cc-legal-entity',
|
||||
templateUrl: 'legal-entity.component.html'
|
||||
})
|
||||
export class LegalEntityComponent implements OnInit {
|
||||
@Input()
|
||||
form: FormGroup;
|
||||
|
||||
@Input()
|
||||
initialValue: LegalEntity;
|
||||
|
||||
types = [Type.russian_legal_entity, Type.international_legal_entity];
|
||||
|
||||
selected: Type;
|
||||
|
||||
t = Type;
|
||||
|
||||
constructor(private fb: FormBuilder) {}
|
||||
|
||||
ngOnInit() {
|
||||
const russianLegalEntity = get(this, 'initialValue.russian_legal_entity', null);
|
||||
const internationalLegalEntity = get(this, 'initialValue.international_legal_entity', null);
|
||||
if (russianLegalEntity) {
|
||||
this.selected = Type.russian_legal_entity;
|
||||
this.select();
|
||||
}
|
||||
if (internationalLegalEntity) {
|
||||
this.selected = Type.international_legal_entity;
|
||||
this.select();
|
||||
}
|
||||
}
|
||||
|
||||
select() {
|
||||
switch (this.selected) {
|
||||
case Type.russian_legal_entity:
|
||||
this.form.removeControl(Type.international_legal_entity);
|
||||
this.form.registerControl(Type.russian_legal_entity, this.fb.group({}));
|
||||
break;
|
||||
case Type.international_legal_entity:
|
||||
this.form.removeControl(Type.russian_legal_entity);
|
||||
this.form.registerControl(Type.international_legal_entity, this.fb.group({}));
|
||||
break;
|
||||
}
|
||||
this.form.updateValueAndValidity();
|
||||
}
|
||||
}
|
@ -0,0 +1,69 @@
|
||||
<cc-form-wrapper name="Russian legal entity">
|
||||
<form [formGroup]="form">
|
||||
<div fxLayout="column">
|
||||
<mat-form-field fxFlex>
|
||||
<input
|
||||
matInput
|
||||
placeholder="Registered name"
|
||||
formControlName="registered_name"
|
||||
required
|
||||
/>
|
||||
</mat-form-field>
|
||||
<mat-form-field fxFlex>
|
||||
<input
|
||||
matInput
|
||||
placeholder="Registered number"
|
||||
formControlName="registered_number"
|
||||
required
|
||||
/>
|
||||
</mat-form-field>
|
||||
<mat-form-field fxFlex>
|
||||
<input matInput placeholder="INN" formControlName="inn" required />
|
||||
</mat-form-field>
|
||||
<mat-form-field fxFlex>
|
||||
<input
|
||||
matInput
|
||||
placeholder="Actual address"
|
||||
formControlName="actual_address"
|
||||
required
|
||||
/>
|
||||
</mat-form-field>
|
||||
<mat-form-field fxFlex>
|
||||
<input
|
||||
matInput
|
||||
placeholder="Post address"
|
||||
formControlName="post_address"
|
||||
required
|
||||
/>
|
||||
</mat-form-field>
|
||||
<mat-form-field fxFlex>
|
||||
<input
|
||||
matInput
|
||||
placeholder="Representative position"
|
||||
formControlName="representative_position"
|
||||
required
|
||||
/>
|
||||
</mat-form-field>
|
||||
<mat-form-field fxFlex>
|
||||
<input
|
||||
matInput
|
||||
placeholder="Representative full name"
|
||||
formControlName="representative_full_name"
|
||||
required
|
||||
/>
|
||||
</mat-form-field>
|
||||
<mat-form-field fxFlex>
|
||||
<input
|
||||
matInput
|
||||
placeholder="Representative document"
|
||||
formControlName="representative_document"
|
||||
required
|
||||
/>
|
||||
</mat-form-field>
|
||||
<cc-nested-form-wrapper caption="russian_bank_account">
|
||||
<cc-russian-bank-account fxFlex [form]="form.get('russian_bank_account')">
|
||||
</cc-russian-bank-account>
|
||||
</cc-nested-form-wrapper>
|
||||
</div>
|
||||
</form>
|
||||
</cc-form-wrapper>
|
@ -0,0 +1,40 @@
|
||||
import { Component, Input, OnInit } from '@angular/core';
|
||||
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
|
||||
import get from 'lodash-es/get';
|
||||
import { RussianLegalEntity } from '../../../../../../../thrift-services/damsel/gen-model/domain';
|
||||
|
||||
@Component({
|
||||
selector: 'cc-russian-legal-entity',
|
||||
templateUrl: 'russian-legal-entity.component.html'
|
||||
})
|
||||
export class RussianLegalEntityComponent implements OnInit {
|
||||
@Input()
|
||||
form: FormGroup;
|
||||
|
||||
@Input()
|
||||
initialValue: RussianLegalEntity;
|
||||
|
||||
constructor(private fb: FormBuilder) {}
|
||||
|
||||
ngOnInit() {
|
||||
const control = value => this.fb.control(value, Validators.required);
|
||||
const registeredName = get(this, 'initialValue.registered_name', '');
|
||||
const registeredNumber = get(this, 'initialValue.registered_number', '');
|
||||
const inn = get(this, 'initialValue.inn', '');
|
||||
const actualAddress = get(this, 'initialValue.actual_address', '');
|
||||
const postAddress = get(this, 'initialValue.post_address', '');
|
||||
const representativePosition = get(this, 'initialValue.representative_position', '');
|
||||
const representativeFullName = get(this, 'initialValue.representative_full_name', '');
|
||||
const representativeDocument = get(this, 'initialValue.representative_document', '');
|
||||
this.form.registerControl('registered_name', control(registeredName));
|
||||
this.form.registerControl('registered_number', control(registeredNumber));
|
||||
this.form.registerControl('inn', control(inn));
|
||||
this.form.registerControl('actual_address', control(actualAddress));
|
||||
this.form.registerControl('post_address', control(postAddress));
|
||||
this.form.registerControl('representative_position', control(representativePosition));
|
||||
this.form.registerControl('representative_full_name', control(representativeFullName));
|
||||
this.form.registerControl('representative_document', control(representativeDocument));
|
||||
this.form.registerControl('russian_bank_account', this.fb.group({}));
|
||||
this.form.updateValueAndValidity();
|
||||
}
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
<form [formGroup]="form">
|
||||
<mat-form-field fxFlex>
|
||||
<mat-select placeholder="Select payment institution" formControlName="id">
|
||||
<mat-option
|
||||
*ngFor="let paymentInstitution of (paymentInstitutions$ | async)"
|
||||
[value]="paymentInstitution.ref.id"
|
||||
required
|
||||
>
|
||||
{{ paymentInstitution.ref.id }} {{ paymentInstitution.data.name }}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
</form>
|
@ -0,0 +1,46 @@
|
||||
import { Component, Input, OnInit } from '@angular/core';
|
||||
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
|
||||
import { map } from 'rxjs/operators';
|
||||
import sortBy from 'lodash-es/sortBy';
|
||||
import { Observable } from 'rxjs';
|
||||
import get from 'lodash-es/get';
|
||||
import {
|
||||
PaymentInstitutionObject,
|
||||
PaymentInstitutionRef
|
||||
} from '../../../../../../thrift-services/damsel/gen-model/domain';
|
||||
import { DomainTypedManager } from '../../../../../../thrift-services';
|
||||
|
||||
@Component({
|
||||
selector: 'cc-payment-institution-ref',
|
||||
templateUrl: 'payment-institution-ref.component.html'
|
||||
})
|
||||
export class PaymentInstitutionRefComponent implements OnInit {
|
||||
@Input()
|
||||
form: FormGroup;
|
||||
|
||||
@Input()
|
||||
required: boolean;
|
||||
|
||||
@Input()
|
||||
initialValue: PaymentInstitutionRef;
|
||||
|
||||
paymentInstitutions$: Observable<PaymentInstitutionObject[]>;
|
||||
|
||||
constructor(private fb: FormBuilder, private dtm: DomainTypedManager) {}
|
||||
|
||||
ngOnInit() {
|
||||
this.paymentInstitutions$ = this.dtm
|
||||
.getPaymentInstitutions()
|
||||
.pipe(
|
||||
map(paymentInstitutions =>
|
||||
sortBy(paymentInstitutions, paymentInstitution => paymentInstitution.ref.id)
|
||||
)
|
||||
);
|
||||
const paymentInstitutionId = get(this, 'initialValue.id', '');
|
||||
this.form.registerControl(
|
||||
'id',
|
||||
this.fb.control(paymentInstitutionId, this.required ? Validators.required : null)
|
||||
);
|
||||
this.form.updateValueAndValidity();
|
||||
}
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
<cc-form-wrapper name="International bank account">
|
||||
<form [formGroup]="form" fxLayout="column">
|
||||
<mat-form-field>
|
||||
<input matInput placeholder="Number" formControlName="number" />
|
||||
</mat-form-field>
|
||||
<mat-form-field>
|
||||
<input matInput placeholder="IBAN" formControlName="iban" />
|
||||
</mat-form-field>
|
||||
<div fxLayout="column" fxLayoutGap="15px">
|
||||
<section>
|
||||
<mat-checkbox [checked]="isBankDetails" (change)="detailsChange($event.checked)"
|
||||
>International bank details</mat-checkbox
|
||||
>
|
||||
</section>
|
||||
<cc-international-bank-details
|
||||
*ngIf="isBankDetails"
|
||||
[form]="form.get('bank')"
|
||||
[initialValue]="initialValue?.bank"
|
||||
>
|
||||
</cc-international-bank-details>
|
||||
<section>
|
||||
<mat-checkbox
|
||||
[checked]="isCorrespondentAccount"
|
||||
(change)="accountChange($event.checked)"
|
||||
>Correspondent account</mat-checkbox
|
||||
>
|
||||
</section>
|
||||
<div fxLayout>
|
||||
<div fxFlex="10"></div>
|
||||
<cc-international-bank-account
|
||||
fxFlex="90"
|
||||
*ngIf="isCorrespondentAccount"
|
||||
[form]="form.get('correspondent_account')"
|
||||
[initialValue]="initialValue?.correspondent_account"
|
||||
>
|
||||
</cc-international-bank-account>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</cc-form-wrapper>
|
@ -0,0 +1,52 @@
|
||||
import { Component, Input, OnInit } from '@angular/core';
|
||||
import { FormBuilder, FormGroup } from '@angular/forms';
|
||||
import get from 'lodash-es/get';
|
||||
import { InternationalBankAccount } from '../../../../../../../thrift-services/damsel/gen-model/domain';
|
||||
|
||||
@Component({
|
||||
selector: 'cc-international-bank-account',
|
||||
templateUrl: 'international-bank-account.component.html'
|
||||
})
|
||||
export class InternationalBankAccountComponent implements OnInit {
|
||||
@Input()
|
||||
form: FormGroup;
|
||||
|
||||
@Input()
|
||||
initialValue: InternationalBankAccount;
|
||||
|
||||
isBankDetails = false;
|
||||
|
||||
isCorrespondentAccount = false;
|
||||
|
||||
constructor(private fb: FormBuilder) {}
|
||||
|
||||
ngOnInit() {
|
||||
const number = get(this, 'initialValue.number', '');
|
||||
const iban = get(this, 'initialValue.iban', '');
|
||||
this.form.registerControl('number', this.fb.control(number));
|
||||
this.form.registerControl('iban', this.fb.control(iban));
|
||||
const bank = get(this, 'initialValue.bank', null);
|
||||
if (bank) {
|
||||
this.detailsChange(true);
|
||||
}
|
||||
const account = get(this, 'initialValue.correspondent_account', null);
|
||||
if (account) {
|
||||
this.accountChange(true);
|
||||
}
|
||||
this.form.updateValueAndValidity();
|
||||
}
|
||||
|
||||
detailsChange(showDetails: boolean) {
|
||||
this.isBankDetails = showDetails;
|
||||
this.isBankDetails
|
||||
? this.form.registerControl('bank', this.fb.group({}))
|
||||
: this.form.removeControl('bank');
|
||||
}
|
||||
|
||||
accountChange(showCorrespondentAccount: boolean) {
|
||||
this.isCorrespondentAccount = showCorrespondentAccount;
|
||||
this.isCorrespondentAccount
|
||||
? this.form.registerControl('correspondent_account', this.fb.group({}))
|
||||
: this.form.removeControl('correspondent_account');
|
||||
}
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
<form [formGroup]="form" fxLayout="column">
|
||||
<mat-form-field> <input matInput placeholder="BIC" formControlName="bic" /> </mat-form-field>
|
||||
<mat-form-field> <input matInput placeholder="Name" formControlName="name" /> </mat-form-field>
|
||||
<mat-form-field>
|
||||
<input matInput placeholder="Address" formControlName="address" />
|
||||
</mat-form-field>
|
||||
<mat-form-field>
|
||||
<input matInput placeholder="ABA routing transit number" formControlName="aba_rtn" />
|
||||
</mat-form-field>
|
||||
<mat-form-field>
|
||||
<input matInput placeholder="Country code" formControlName="country" />
|
||||
</mat-form-field>
|
||||
</form>
|
@ -0,0 +1,33 @@
|
||||
import { Component, Input, OnInit } from '@angular/core';
|
||||
import { FormBuilder, FormGroup } from '@angular/forms';
|
||||
import get from 'lodash-es/get';
|
||||
import { InternationalBankDetails } from '../../../../../../../../thrift-services/damsel/gen-model/domain';
|
||||
|
||||
@Component({
|
||||
selector: 'cc-international-bank-details',
|
||||
templateUrl: 'international-bank-details.component.html'
|
||||
})
|
||||
export class InternationalBankDetailsComponent implements OnInit {
|
||||
@Input()
|
||||
form: FormGroup;
|
||||
|
||||
@Input()
|
||||
initialValue: InternationalBankDetails;
|
||||
|
||||
constructor(private fb: FormBuilder) {}
|
||||
|
||||
ngOnInit() {
|
||||
const control = (data = '') => this.fb.control(data);
|
||||
const bic = get(this, 'initialValue.bic', '');
|
||||
const country = get(this, 'initialValue.country', '');
|
||||
const name = get(this, 'initialValue.name', '');
|
||||
const address = get(this, 'initialValue.address', '');
|
||||
const abaRtn = get(this, 'initialValue.aba_rtn', '');
|
||||
this.form.registerControl('bic', control(bic));
|
||||
this.form.registerControl('country', control(country)); // Residence enum
|
||||
this.form.registerControl('name', control(name));
|
||||
this.form.registerControl('address', control(address));
|
||||
this.form.registerControl('aba_rtn', control(abaRtn));
|
||||
this.form.updateValueAndValidity();
|
||||
}
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
<div fxLayout="column">
|
||||
<mat-form-field>
|
||||
<mat-select
|
||||
placeholder="Payout tool info"
|
||||
[(value)]="selected"
|
||||
(selectionChange)="select()"
|
||||
>
|
||||
<mat-option *ngFor="let type of types" [value]="type">{{ type }}</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
<cc-russian-bank-account
|
||||
*ngIf="selected === t.russian_bank_account"
|
||||
[form]="form.get(t.russian_bank_account)"
|
||||
[initialValue]="initialValue?.russian_bank_account"
|
||||
>
|
||||
</cc-russian-bank-account>
|
||||
<cc-international-bank-account
|
||||
*ngIf="selected === t.international_bank_account"
|
||||
[form]="form.get(t.international_bank_account)"
|
||||
[initialValue]="initialValue?.international_bank_account"
|
||||
>
|
||||
</cc-international-bank-account>
|
||||
<cc-wallet-info *ngIf="selected === t.wallet_info" [form]="form.get(t.wallet_info)">
|
||||
</cc-wallet-info>
|
||||
</div>
|
@ -0,0 +1,71 @@
|
||||
import { Component, Input, OnInit } from '@angular/core';
|
||||
import { FormBuilder, FormGroup } from '@angular/forms';
|
||||
import get from 'lodash-es/get';
|
||||
import { PayoutToolInfo } from '../../../../../../thrift-services/damsel/gen-model/domain';
|
||||
|
||||
enum Type {
|
||||
russian_bank_account = 'russian_bank_account',
|
||||
international_bank_account = 'international_bank_account',
|
||||
wallet_info = 'wallet_info'
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'cc-payout-tool-info',
|
||||
templateUrl: 'payout-tool-info.component.html'
|
||||
})
|
||||
export class PayoutToolInfoComponent implements OnInit {
|
||||
@Input()
|
||||
form: FormGroup;
|
||||
|
||||
@Input()
|
||||
initialValue: PayoutToolInfo;
|
||||
|
||||
selected: Type;
|
||||
|
||||
types = [Type.russian_bank_account, Type.international_bank_account, Type.wallet_info];
|
||||
|
||||
t = Type;
|
||||
|
||||
constructor(private fb: FormBuilder) {}
|
||||
|
||||
ngOnInit() {
|
||||
const russianBankAccount = get(this, 'initialValue.russian_bank_account', null);
|
||||
const internationalBankAccount = get(this, 'initialValue.international_bank_account', null);
|
||||
const walletInfo = get(this, 'initialValue.wallet_info', null);
|
||||
if (russianBankAccount) {
|
||||
this.selected = Type.russian_bank_account;
|
||||
}
|
||||
if (internationalBankAccount) {
|
||||
this.selected = Type.international_bank_account;
|
||||
}
|
||||
if (walletInfo) {
|
||||
this.selected = Type.wallet_info;
|
||||
}
|
||||
this.select();
|
||||
this.form.updateValueAndValidity();
|
||||
}
|
||||
|
||||
select() {
|
||||
switch (this.selected) {
|
||||
case Type.russian_bank_account:
|
||||
this.clearControl();
|
||||
this.form.registerControl(Type.russian_bank_account, this.fb.group({}));
|
||||
break;
|
||||
case Type.international_bank_account:
|
||||
this.clearControl();
|
||||
this.form.registerControl(Type.international_bank_account, this.fb.group({}));
|
||||
break;
|
||||
case Type.wallet_info:
|
||||
this.clearControl();
|
||||
const walletInfo = get(this, 'initialValue.wallet_info', {});
|
||||
this.form.registerControl(Type.wallet_info, this.fb.group(walletInfo));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private clearControl() {
|
||||
this.types.forEach(type => {
|
||||
this.form.removeControl(type);
|
||||
});
|
||||
}
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
<cc-form-wrapper name="Russian bank account">
|
||||
<form [formGroup]="form" fxLayout="column">
|
||||
<mat-form-field>
|
||||
<input matInput placeholder="Account" formControlName="account" required />
|
||||
</mat-form-field>
|
||||
<mat-form-field>
|
||||
<input matInput placeholder="Bank name" formControlName="bank_name" required />
|
||||
</mat-form-field>
|
||||
<mat-form-field>
|
||||
<input
|
||||
matInput
|
||||
placeholder="Bank post account"
|
||||
formControlName="bank_post_account"
|
||||
required
|
||||
/>
|
||||
</mat-form-field>
|
||||
<mat-form-field>
|
||||
<input matInput placeholder="Bank bik" formControlName="bank_bik" required />
|
||||
</mat-form-field>
|
||||
</form>
|
||||
</cc-form-wrapper>
|
@ -0,0 +1,31 @@
|
||||
import { Component, Input, OnInit } from '@angular/core';
|
||||
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
|
||||
import get from 'lodash-es/get';
|
||||
import { RussianBankAccount } from '../../../../../../../thrift-services/damsel/gen-model/domain';
|
||||
|
||||
@Component({
|
||||
selector: 'cc-russian-bank-account',
|
||||
templateUrl: 'russian-bank-account.component.html'
|
||||
})
|
||||
export class RussianBankAccountComponent implements OnInit {
|
||||
@Input()
|
||||
form: FormGroup;
|
||||
|
||||
@Input()
|
||||
initialValue: RussianBankAccount;
|
||||
|
||||
constructor(private fb: FormBuilder) {}
|
||||
|
||||
ngOnInit() {
|
||||
const control = value => this.fb.control(value, Validators.required);
|
||||
const account = get(this, 'initialValue.account', '');
|
||||
const bankName = get(this, 'initialValue.bank_name', '');
|
||||
const bankPostAccount = get(this, 'initialValue.bank_post_account', '');
|
||||
const bankBik = get(this, 'initialValue.bank_bik', '');
|
||||
this.form.registerControl('account', control(account));
|
||||
this.form.registerControl('bank_name', control(bankName));
|
||||
this.form.registerControl('bank_post_account', control(bankPostAccount));
|
||||
this.form.registerControl('bank_bik', control(bankBik));
|
||||
this.form.updateValueAndValidity();
|
||||
}
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
<cc-form-wrapper name="Wallet Info">
|
||||
<form [formGroup]="form" fxLayout="column">
|
||||
<mat-form-field>
|
||||
<input matInput placeholder="Wallet ID" formControlName="wallet_id" required />
|
||||
</mat-form-field>
|
||||
</form>
|
||||
</cc-form-wrapper>
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user