creating FHIR components based on generic list
see https://github.com/synthetichealth/fhir-visualizers/blob/master/src/index.js
This commit is contained in:
parent
5f71891970
commit
48c8873f18
|
@ -24,7 +24,7 @@
|
|||
"@fortawesome/free-solid-svg-icons": "^6.2.0",
|
||||
"@ng-bootstrap/ng-bootstrap": "10.0.0",
|
||||
"@panva/oauth4webapi": "^1.1.3",
|
||||
"angular-datatables": "^14.0.0",
|
||||
"@swimlane/ngx-datatable": "^20.0.0",
|
||||
"bootstrap": "^4.4.1",
|
||||
"chart.js": "2.9.4",
|
||||
"fhirclient": "^2.5.1",
|
||||
|
@ -3329,6 +3329,20 @@
|
|||
"yarn": ">= 1.13.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@swimlane/ngx-datatable": {
|
||||
"version": "20.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@swimlane/ngx-datatable/-/ngx-datatable-20.0.0.tgz",
|
||||
"integrity": "sha512-fok9xzOA5UqhmoRKHpEz25k2wXD/ZGtAAeTQqkn/FpyLgPtdWV2OF/wNIyIZaDJ8jBlNoeHTnJnkDONnFGV93A==",
|
||||
"dependencies": {
|
||||
"tslib": "^2.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@angular/common": ">=11.0.2",
|
||||
"@angular/core": ">=11.0.2",
|
||||
"@angular/platform-browser": ">=11.0.2",
|
||||
"rxjs": "^6.6.3"
|
||||
}
|
||||
},
|
||||
"node_modules/@tootallnate/once": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz",
|
||||
|
@ -3950,87 +3964,6 @@
|
|||
"ajv": "^6.9.1"
|
||||
}
|
||||
},
|
||||
"node_modules/angular-datatables": {
|
||||
"version": "14.0.0",
|
||||
"resolved": "https://registry.npmjs.org/angular-datatables/-/angular-datatables-14.0.0.tgz",
|
||||
"integrity": "sha512-IdJdS/IGAFKcWKCM3PrgHt8YIyCGxUKaPQGQom+5YvAcIMKuRwgB7aYT2H3+zUsJBNms2Yaeh95ABNT+yqOwLQ==",
|
||||
"dependencies": {
|
||||
"codelyzer": "^6.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/angular-datatables/node_modules/@angular/compiler": {
|
||||
"version": "9.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-9.0.0.tgz",
|
||||
"integrity": "sha512-ctjwuntPfZZT2mNj2NDIVu51t9cvbhl/16epc5xEwyzyDt76pX9UgwvY+MbXrf/C/FWwdtmNtfP698BKI+9leQ==",
|
||||
"peerDependencies": {
|
||||
"tslib": "^1.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/angular-datatables/node_modules/@angular/core": {
|
||||
"version": "9.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@angular/core/-/core-9.0.0.tgz",
|
||||
"integrity": "sha512-6Pxgsrf0qF9iFFqmIcWmjJGkkCaCm6V5QNnxMy2KloO3SDq6QuMVRbN9RtC8Urmo25LP+eZ6ZgYqFYpdD8Hd9w==",
|
||||
"peerDependencies": {
|
||||
"rxjs": "^6.5.3",
|
||||
"tslib": "^1.10.0",
|
||||
"zone.js": "~0.10.2"
|
||||
}
|
||||
},
|
||||
"node_modules/angular-datatables/node_modules/app-root-path": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/app-root-path/-/app-root-path-3.1.0.tgz",
|
||||
"integrity": "sha512-biN3PwB2gUtjaYy/isrU3aNWI5w+fAfvHkSvCKeQGxhmYpwKFUxudR3Yya+KqVRHBmEDYh+/lTozYCFbmzX4nA==",
|
||||
"engines": {
|
||||
"node": ">= 6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/angular-datatables/node_modules/codelyzer": {
|
||||
"version": "6.0.2",
|
||||
"resolved": "https://registry.npmjs.org/codelyzer/-/codelyzer-6.0.2.tgz",
|
||||
"integrity": "sha512-v3+E0Ucu2xWJMOJ2fA/q9pDT/hlxHftHGPUay1/1cTgyPV5JTHFdO9hqo837Sx2s9vKBMTt5gO+lhF95PO6J+g==",
|
||||
"dependencies": {
|
||||
"@angular/compiler": "9.0.0",
|
||||
"@angular/core": "9.0.0",
|
||||
"app-root-path": "^3.0.0",
|
||||
"aria-query": "^3.0.0",
|
||||
"axobject-query": "2.0.2",
|
||||
"css-selector-tokenizer": "^0.7.1",
|
||||
"cssauron": "^1.4.0",
|
||||
"damerau-levenshtein": "^1.0.4",
|
||||
"rxjs": "^6.5.3",
|
||||
"semver-dsl": "^1.0.1",
|
||||
"source-map": "^0.5.7",
|
||||
"sprintf-js": "^1.1.2",
|
||||
"tslib": "^1.10.0",
|
||||
"zone.js": "~0.10.3"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@angular/compiler": ">=2.3.1 <13.0.0 || ^12.0.0-next || ^12.1.0-next || ^12.2.0-next",
|
||||
"@angular/core": ">=2.3.1 <13.0.0 || ^12.0.0-next || ^12.1.0-next || ^12.2.0-next",
|
||||
"tslint": "^5.0.0 || ^6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/angular-datatables/node_modules/source-map": {
|
||||
"version": "0.5.7",
|
||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
|
||||
"integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/angular-datatables/node_modules/tslib": {
|
||||
"version": "1.14.1",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
|
||||
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
|
||||
},
|
||||
"node_modules/angular-datatables/node_modules/zone.js": {
|
||||
"version": "0.10.3",
|
||||
"resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.10.3.tgz",
|
||||
"integrity": "sha512-LXVLVEq0NNOqK/fLJo3d0kfzd4sxwn2/h67/02pjCjfKDxgx1i9QqpvtHD8CrBnSSwMw5+dy11O7FRX5mkO7Cg=="
|
||||
},
|
||||
"node_modules/ansi-colors": {
|
||||
"version": "4.1.3",
|
||||
"resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz",
|
||||
|
@ -4166,6 +4099,7 @@
|
|||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/aria-query/-/aria-query-3.0.0.tgz",
|
||||
"integrity": "sha512-majUxHgLehQTeSA+hClx+DY09OVUqG3GtezWkF1krgLGNdlDu9l9V8DaqNMWbq4Eddc8wsyDA0hpDUtnYxQEXw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"ast-types-flow": "0.0.7",
|
||||
"commander": "^2.11.0"
|
||||
|
@ -4234,7 +4168,8 @@
|
|||
"node_modules/ast-types-flow": {
|
||||
"version": "0.0.7",
|
||||
"resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.7.tgz",
|
||||
"integrity": "sha512-eBvWn1lvIApYMhzQMsu9ciLfkBY499mFZlNqG+/9WR7PVlroQw0vG30cOQQbaKz3sCEc44TAOu2ykzqXSNnwag=="
|
||||
"integrity": "sha512-eBvWn1lvIApYMhzQMsu9ciLfkBY499mFZlNqG+/9WR7PVlroQw0vG30cOQQbaKz3sCEc44TAOu2ykzqXSNnwag==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/asynckit": {
|
||||
"version": "0.4.0",
|
||||
|
@ -4315,6 +4250,7 @@
|
|||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.0.2.tgz",
|
||||
"integrity": "sha512-MCeek8ZH7hKyO1rWUbKNQBbl4l2eY0ntk7OGi+q0RlafrCnfPxC06WZA+uebCfmYp4mNU9jRBP1AhGyf8+W3ww==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"ast-types-flow": "0.0.7"
|
||||
}
|
||||
|
@ -5134,7 +5070,8 @@
|
|||
"node_modules/commander": {
|
||||
"version": "2.20.3",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
|
||||
"integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ=="
|
||||
"integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/commondir": {
|
||||
"version": "1.0.1",
|
||||
|
@ -5721,6 +5658,7 @@
|
|||
"version": "0.7.3",
|
||||
"resolved": "https://registry.npmjs.org/css-selector-tokenizer/-/css-selector-tokenizer-0.7.3.tgz",
|
||||
"integrity": "sha512-jWQv3oCEL5kMErj4wRnK/OPoBi0D+P1FR2cDCKYPaMeD2eW3/mttav8HT4hT1CKopiJI/psEULjkClhvJo4Lvg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"cssesc": "^3.0.0",
|
||||
"fastparse": "^1.1.2"
|
||||
|
@ -5751,6 +5689,7 @@
|
|||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/cssauron/-/cssauron-1.4.0.tgz",
|
||||
"integrity": "sha512-Ht70DcFBh+/ekjVrYS2PlDMdSQEl3OFNmjK6lcn49HptBgilXf/Zwg4uFh9Xn0pX3Q8YOkSjIFOfK2osvdqpBw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"through": "X.X.X"
|
||||
}
|
||||
|
@ -5769,6 +5708,7 @@
|
|||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
|
||||
"integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"cssesc": "bin/cssesc"
|
||||
},
|
||||
|
@ -5785,7 +5725,8 @@
|
|||
"node_modules/damerau-levenshtein": {
|
||||
"version": "1.0.8",
|
||||
"resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz",
|
||||
"integrity": "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA=="
|
||||
"integrity": "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/dashdash": {
|
||||
"version": "1.14.1",
|
||||
|
@ -7154,7 +7095,8 @@
|
|||
"node_modules/fastparse": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/fastparse/-/fastparse-1.1.2.tgz",
|
||||
"integrity": "sha512-483XLLxTVIwWK3QTrMGRqUfUpoOs/0hbQrl2oz4J0pAcm3A3bu84wxTFqGqkJzewCLdME38xJLJAxBABfQT8sQ=="
|
||||
"integrity": "sha512-483XLLxTVIwWK3QTrMGRqUfUpoOs/0hbQrl2oz4J0pAcm3A3bu84wxTFqGqkJzewCLdME38xJLJAxBABfQT8sQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/fastq": {
|
||||
"version": "1.13.0",
|
||||
|
@ -12580,6 +12522,7 @@
|
|||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/semver-dsl/-/semver-dsl-1.0.1.tgz",
|
||||
"integrity": "sha512-e8BOaTo007E3dMuQQTnPdalbKTABKNS7UxoBIDnwOqRa+QwMrCPjynB8zAlPF6xlqUfdLPPLIJ13hJNmhtq8Ng==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"semver": "^5.3.0"
|
||||
}
|
||||
|
@ -12588,6 +12531,7 @@
|
|||
"version": "5.7.1",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
|
||||
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"semver": "bin/semver"
|
||||
}
|
||||
|
@ -13092,7 +13036,8 @@
|
|||
"node_modules/sprintf-js": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz",
|
||||
"integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug=="
|
||||
"integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/sshpk": {
|
||||
"version": "1.17.0",
|
||||
|
@ -13419,7 +13364,8 @@
|
|||
"node_modules/through": {
|
||||
"version": "2.3.8",
|
||||
"resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
|
||||
"integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg=="
|
||||
"integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/thunky": {
|
||||
"version": "1.1.0",
|
||||
|
@ -16837,6 +16783,14 @@
|
|||
"jsonc-parser": "3.1.0"
|
||||
}
|
||||
},
|
||||
"@swimlane/ngx-datatable": {
|
||||
"version": "20.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@swimlane/ngx-datatable/-/ngx-datatable-20.0.0.tgz",
|
||||
"integrity": "sha512-fok9xzOA5UqhmoRKHpEz25k2wXD/ZGtAAeTQqkn/FpyLgPtdWV2OF/wNIyIZaDJ8jBlNoeHTnJnkDONnFGV93A==",
|
||||
"requires": {
|
||||
"tslib": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"@tootallnate/once": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz",
|
||||
|
@ -17407,67 +17361,6 @@
|
|||
"integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==",
|
||||
"dev": true
|
||||
},
|
||||
"angular-datatables": {
|
||||
"version": "14.0.0",
|
||||
"resolved": "https://registry.npmjs.org/angular-datatables/-/angular-datatables-14.0.0.tgz",
|
||||
"integrity": "sha512-IdJdS/IGAFKcWKCM3PrgHt8YIyCGxUKaPQGQom+5YvAcIMKuRwgB7aYT2H3+zUsJBNms2Yaeh95ABNT+yqOwLQ==",
|
||||
"requires": {
|
||||
"codelyzer": "^6.0.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"@angular/compiler": {
|
||||
"version": "9.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-9.0.0.tgz",
|
||||
"integrity": "sha512-ctjwuntPfZZT2mNj2NDIVu51t9cvbhl/16epc5xEwyzyDt76pX9UgwvY+MbXrf/C/FWwdtmNtfP698BKI+9leQ=="
|
||||
},
|
||||
"@angular/core": {
|
||||
"version": "9.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@angular/core/-/core-9.0.0.tgz",
|
||||
"integrity": "sha512-6Pxgsrf0qF9iFFqmIcWmjJGkkCaCm6V5QNnxMy2KloO3SDq6QuMVRbN9RtC8Urmo25LP+eZ6ZgYqFYpdD8Hd9w=="
|
||||
},
|
||||
"app-root-path": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/app-root-path/-/app-root-path-3.1.0.tgz",
|
||||
"integrity": "sha512-biN3PwB2gUtjaYy/isrU3aNWI5w+fAfvHkSvCKeQGxhmYpwKFUxudR3Yya+KqVRHBmEDYh+/lTozYCFbmzX4nA=="
|
||||
},
|
||||
"codelyzer": {
|
||||
"version": "6.0.2",
|
||||
"resolved": "https://registry.npmjs.org/codelyzer/-/codelyzer-6.0.2.tgz",
|
||||
"integrity": "sha512-v3+E0Ucu2xWJMOJ2fA/q9pDT/hlxHftHGPUay1/1cTgyPV5JTHFdO9hqo837Sx2s9vKBMTt5gO+lhF95PO6J+g==",
|
||||
"requires": {
|
||||
"@angular/compiler": "9.0.0",
|
||||
"@angular/core": "9.0.0",
|
||||
"app-root-path": "^3.0.0",
|
||||
"aria-query": "^3.0.0",
|
||||
"axobject-query": "2.0.2",
|
||||
"css-selector-tokenizer": "^0.7.1",
|
||||
"cssauron": "^1.4.0",
|
||||
"damerau-levenshtein": "^1.0.4",
|
||||
"rxjs": "^6.5.3",
|
||||
"semver-dsl": "^1.0.1",
|
||||
"source-map": "^0.5.7",
|
||||
"sprintf-js": "^1.1.2",
|
||||
"tslib": "^1.10.0",
|
||||
"zone.js": "~0.10.3"
|
||||
}
|
||||
},
|
||||
"source-map": {
|
||||
"version": "0.5.7",
|
||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
|
||||
"integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ=="
|
||||
},
|
||||
"tslib": {
|
||||
"version": "1.14.1",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
|
||||
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
|
||||
},
|
||||
"zone.js": {
|
||||
"version": "0.10.3",
|
||||
"resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.10.3.tgz",
|
||||
"integrity": "sha512-LXVLVEq0NNOqK/fLJo3d0kfzd4sxwn2/h67/02pjCjfKDxgx1i9QqpvtHD8CrBnSSwMw5+dy11O7FRX5mkO7Cg=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"ansi-colors": {
|
||||
"version": "4.1.3",
|
||||
"resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz",
|
||||
|
@ -17574,6 +17467,7 @@
|
|||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/aria-query/-/aria-query-3.0.0.tgz",
|
||||
"integrity": "sha512-majUxHgLehQTeSA+hClx+DY09OVUqG3GtezWkF1krgLGNdlDu9l9V8DaqNMWbq4Eddc8wsyDA0hpDUtnYxQEXw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ast-types-flow": "0.0.7",
|
||||
"commander": "^2.11.0"
|
||||
|
@ -17630,7 +17524,8 @@
|
|||
"ast-types-flow": {
|
||||
"version": "0.0.7",
|
||||
"resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.7.tgz",
|
||||
"integrity": "sha512-eBvWn1lvIApYMhzQMsu9ciLfkBY499mFZlNqG+/9WR7PVlroQw0vG30cOQQbaKz3sCEc44TAOu2ykzqXSNnwag=="
|
||||
"integrity": "sha512-eBvWn1lvIApYMhzQMsu9ciLfkBY499mFZlNqG+/9WR7PVlroQw0vG30cOQQbaKz3sCEc44TAOu2ykzqXSNnwag==",
|
||||
"dev": true
|
||||
},
|
||||
"asynckit": {
|
||||
"version": "0.4.0",
|
||||
|
@ -17680,6 +17575,7 @@
|
|||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.0.2.tgz",
|
||||
"integrity": "sha512-MCeek8ZH7hKyO1rWUbKNQBbl4l2eY0ntk7OGi+q0RlafrCnfPxC06WZA+uebCfmYp4mNU9jRBP1AhGyf8+W3ww==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ast-types-flow": "0.0.7"
|
||||
}
|
||||
|
@ -18299,7 +18195,8 @@
|
|||
"commander": {
|
||||
"version": "2.20.3",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
|
||||
"integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ=="
|
||||
"integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
|
||||
"dev": true
|
||||
},
|
||||
"commondir": {
|
||||
"version": "1.0.1",
|
||||
|
@ -18752,6 +18649,7 @@
|
|||
"version": "0.7.3",
|
||||
"resolved": "https://registry.npmjs.org/css-selector-tokenizer/-/css-selector-tokenizer-0.7.3.tgz",
|
||||
"integrity": "sha512-jWQv3oCEL5kMErj4wRnK/OPoBi0D+P1FR2cDCKYPaMeD2eW3/mttav8HT4hT1CKopiJI/psEULjkClhvJo4Lvg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"cssesc": "^3.0.0",
|
||||
"fastparse": "^1.1.2"
|
||||
|
@ -18767,6 +18665,7 @@
|
|||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/cssauron/-/cssauron-1.4.0.tgz",
|
||||
"integrity": "sha512-Ht70DcFBh+/ekjVrYS2PlDMdSQEl3OFNmjK6lcn49HptBgilXf/Zwg4uFh9Xn0pX3Q8YOkSjIFOfK2osvdqpBw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"through": "X.X.X"
|
||||
}
|
||||
|
@ -18780,7 +18679,8 @@
|
|||
"cssesc": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
|
||||
"integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg=="
|
||||
"integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==",
|
||||
"dev": true
|
||||
},
|
||||
"custom-event": {
|
||||
"version": "1.0.1",
|
||||
|
@ -18791,7 +18691,8 @@
|
|||
"damerau-levenshtein": {
|
||||
"version": "1.0.8",
|
||||
"resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz",
|
||||
"integrity": "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA=="
|
||||
"integrity": "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==",
|
||||
"dev": true
|
||||
},
|
||||
"dashdash": {
|
||||
"version": "1.14.1",
|
||||
|
@ -19739,7 +19640,8 @@
|
|||
"fastparse": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/fastparse/-/fastparse-1.1.2.tgz",
|
||||
"integrity": "sha512-483XLLxTVIwWK3QTrMGRqUfUpoOs/0hbQrl2oz4J0pAcm3A3bu84wxTFqGqkJzewCLdME38xJLJAxBABfQT8sQ=="
|
||||
"integrity": "sha512-483XLLxTVIwWK3QTrMGRqUfUpoOs/0hbQrl2oz4J0pAcm3A3bu84wxTFqGqkJzewCLdME38xJLJAxBABfQT8sQ==",
|
||||
"dev": true
|
||||
},
|
||||
"fastq": {
|
||||
"version": "1.13.0",
|
||||
|
@ -23719,6 +23621,7 @@
|
|||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/semver-dsl/-/semver-dsl-1.0.1.tgz",
|
||||
"integrity": "sha512-e8BOaTo007E3dMuQQTnPdalbKTABKNS7UxoBIDnwOqRa+QwMrCPjynB8zAlPF6xlqUfdLPPLIJ13hJNmhtq8Ng==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"semver": "^5.3.0"
|
||||
},
|
||||
|
@ -23726,7 +23629,8 @@
|
|||
"semver": {
|
||||
"version": "5.7.1",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
|
||||
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ=="
|
||||
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -24153,7 +24057,8 @@
|
|||
"sprintf-js": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz",
|
||||
"integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug=="
|
||||
"integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==",
|
||||
"dev": true
|
||||
},
|
||||
"sshpk": {
|
||||
"version": "1.17.0",
|
||||
|
@ -24379,7 +24284,8 @@
|
|||
"through": {
|
||||
"version": "2.3.8",
|
||||
"resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
|
||||
"integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg=="
|
||||
"integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==",
|
||||
"dev": true
|
||||
},
|
||||
"thunky": {
|
||||
"version": "1.1.0",
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
"@fortawesome/free-solid-svg-icons": "^6.2.0",
|
||||
"@ng-bootstrap/ng-bootstrap": "10.0.0",
|
||||
"@panva/oauth4webapi": "^1.1.3",
|
||||
"angular-datatables": "^14.0.0",
|
||||
"@swimlane/ngx-datatable": "^20.0.0",
|
||||
"bootstrap": "^4.4.1",
|
||||
"chart.js": "2.9.4",
|
||||
"fhirclient": "^2.5.1",
|
||||
|
|
|
@ -1,26 +0,0 @@
|
|||
<p class="mg-b-20">A clinical condition, problem, diagnosis, or other event, situation, issue, or clinical concept that has risen to a level of concern.</p>
|
||||
<div class="table-responsive">
|
||||
<table class="table table-bordered mg-b-0">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Condition</th>
|
||||
<th>Clinical Status</th>
|
||||
<th>Verification Status</th>
|
||||
<th>Onset Date</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr *ngFor="let condition of conditionList">
|
||||
<td>
|
||||
{{condition.name}}
|
||||
<small class="text-muted float-right">
|
||||
{{ condition.nameCode}} {{ condition.nameCodeSystem }}
|
||||
</small>
|
||||
</td>
|
||||
<td class="align-middle">{{condition.clinicalStatus}}</td>
|
||||
<td class="align-middle">{{condition.verificationStatus}}</td>
|
||||
<td class="align-middle">{{condition.onset | date:'M/d/yy'}}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
|
@ -1,23 +0,0 @@
|
|||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { ListConditionComponent } from './list-condition.component';
|
||||
|
||||
describe('ListConditionComponent', () => {
|
||||
let component: ListConditionComponent;
|
||||
let fixture: ComponentFixture<ListConditionComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [ ListConditionComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(ListConditionComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
|
@ -1,25 +0,0 @@
|
|||
import {Component, Input, OnInit} from '@angular/core';
|
||||
import {ResourceFhir} from '../../models/fasten/resource_fhir';
|
||||
import {Condition} from '../../models/display/condition';
|
||||
|
||||
@Component({
|
||||
selector: 'app-list-condition',
|
||||
templateUrl: './list-condition.component.html',
|
||||
styleUrls: ['./list-condition.component.scss']
|
||||
})
|
||||
export class ListConditionComponent implements OnInit {
|
||||
|
||||
@Input() resourceList: ResourceFhir[] = []
|
||||
conditionList: Condition[] = []
|
||||
|
||||
constructor() { }
|
||||
|
||||
ngOnInit(): void {
|
||||
let _conditions = this.conditionList
|
||||
this.resourceList.forEach((resource) => {
|
||||
let cond = new Condition(resource.payload)
|
||||
_conditions.push(cond)
|
||||
})
|
||||
}
|
||||
|
||||
}
|
|
@ -1,27 +0,0 @@
|
|||
<p class="mg-b-20">A clinical condition, problem, diagnosis, or other event, situation, issue, or clinical concept that has risen to a level of concern.</p>
|
||||
<div class="table-responsive">
|
||||
<table class="table table-bordered mg-b-0">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Type</th>
|
||||
<th>Reason</th>
|
||||
<th>Class</th>
|
||||
<th>Status</th>
|
||||
<th>Time</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr *ngFor="let encounter of encounterList">
|
||||
<td>
|
||||
<b *ngIf="encounter.encounterType">{{encounter.encounterType}}</b>
|
||||
<span *ngIf="!encounter.encounterType && encounter.encounterClass" class="text-muted">{{encounter.encounterClass}} encounter</span>
|
||||
<small *ngIf="!encounter.encounterType && !encounter.encounterClass" class="text-muted">N/A</small>
|
||||
</td>
|
||||
<td class="align-middle">{{encounter.reason ? encounter.reason : 'N/A' }}</td>
|
||||
<td class="align-middle">{{encounter.encounterClass ? encounter.encounterClass : 'N/A' }}</td>
|
||||
<td class="align-middle">{{encounter.status ? encounter.status : 'N/A'}}</td>
|
||||
<td class="align-middle">-</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
|
@ -1,23 +0,0 @@
|
|||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { ListEncounterComponent } from './list-encounter.component';
|
||||
|
||||
describe('ListEncounterComponent', () => {
|
||||
let component: ListEncounterComponent;
|
||||
let fixture: ComponentFixture<ListEncounterComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [ ListEncounterComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(ListEncounterComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
|
@ -1,25 +0,0 @@
|
|||
import {Component, Input, OnInit} from '@angular/core';
|
||||
import {ResourceFhir} from '../../models/fasten/resource_fhir';
|
||||
import {Condition} from '../../models/display/condition';
|
||||
import {Encounter} from '../../models/display/encounter';
|
||||
|
||||
@Component({
|
||||
selector: 'app-list-encounter',
|
||||
templateUrl: './list-encounter.component.html',
|
||||
styleUrls: ['./list-encounter.component.scss']
|
||||
})
|
||||
export class ListEncounterComponent implements OnInit {
|
||||
|
||||
@Input() resourceList: ResourceFhir[] = []
|
||||
encounterList: Encounter[] = []
|
||||
|
||||
constructor() { }
|
||||
|
||||
ngOnInit(): void {
|
||||
let _encounterList = this.encounterList
|
||||
this.resourceList.forEach((resource) => {
|
||||
let encounter = new Encounter(resource.payload)
|
||||
_encounterList.push(encounter)
|
||||
})
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
import {Component} from '@angular/core';
|
||||
import {GenericColumnDefn, ListGenericResourceComponent} from './list-generic-resource.component';
|
||||
|
||||
@Component({
|
||||
selector: 'app-list-condition',
|
||||
templateUrl: './list-generic-resource.component.html',
|
||||
styleUrls: ['./list-generic-resource.component.scss']
|
||||
})
|
||||
export class ListConditionComponent extends ListGenericResourceComponent {
|
||||
columnDefinitions: GenericColumnDefn[] = [
|
||||
{ title: 'Condition', versions: '*', format: 'code', getter: c => c.code.coding[0] },
|
||||
{ title: 'Date of Onset', versions: '*', format: 'date', getter: c => c.onsetDateTime },
|
||||
{ title: 'Date Resolved', 'versions': '*', format: 'date', getter: c => c.abatementDateTime, defaultValue: 'N/A' },
|
||||
{ title: 'Recorded Date', versions: '*', format: 'date', getter: c => c.recordedDate },
|
||||
{ title: 'Severity', versions: '*', format: 'code', getter: c => c.severity.coding[0] },
|
||||
{ title: 'Body Site', versions: '*', format: 'code', getter: c => c.bodySite[0].coding[0] }
|
||||
]
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
import {Component} from '@angular/core';
|
||||
import {GenericColumnDefn, ListGenericResourceComponent} from './list-generic-resource.component';
|
||||
|
||||
@Component({
|
||||
selector: 'app-list-encounter',
|
||||
templateUrl: './list-generic-resource.component.html',
|
||||
styleUrls: ['./list-generic-resource.component.scss']
|
||||
})
|
||||
export class ListEncounterComponent extends ListGenericResourceComponent {
|
||||
columnDefinitions: GenericColumnDefn[] = [
|
||||
{ title: 'Encounter', versions: '*', format: 'code', getter: e => e.type[0].coding[0] },
|
||||
{ title: 'Period', versions: '*', format: 'period', getter: e => e.period },
|
||||
{ title: 'Diagnosis', versions: '*', getter: e => e.diagnosis?.map(d => d.condition?.reference).join()},
|
||||
{ title: 'Discharge Disposition', versions: '*', format: 'code', getter: e => e.hospitalization?.dischargeDisposition.coding[0] }
|
||||
]
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
<div>
|
||||
<ngx-datatable
|
||||
#table
|
||||
class="bootstrap"
|
||||
[columns]="columns"
|
||||
[columnMode]="ColumnMode.force"
|
||||
[headerHeight]="50"
|
||||
[footerHeight]="50"
|
||||
rowHeight="auto"
|
||||
[limit]="10"
|
||||
[rows]="rows"
|
||||
>
|
||||
</ngx-datatable>
|
||||
</div>
|
|
@ -0,0 +1,23 @@
|
|||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { ListGenericResourceComponent } from './list-generic-resource.component';
|
||||
|
||||
describe('ListGenericResourceComponent', () => {
|
||||
let component: ListGenericResourceComponent;
|
||||
let fixture: ComponentFixture<ListGenericResourceComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [ ListGenericResourceComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(ListGenericResourceComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
|
@ -0,0 +1,74 @@
|
|||
import {Component, Input, OnInit, ViewChild} from '@angular/core';
|
||||
import {DatatableComponent, ColumnMode} from '@swimlane/ngx-datatable';
|
||||
import {ResourceFhir} from '../../models/fasten/resource_fhir';
|
||||
import {FORMATTERS, getPath, obsValue, attributeXTime} from './utils';
|
||||
import {observableToBeFn} from 'rxjs/internal/testing/TestScheduler';
|
||||
|
||||
export class GenericColumnDefn {
|
||||
title: string
|
||||
prop?: string
|
||||
versions?: string
|
||||
format?: string
|
||||
getter: Function
|
||||
defaultValue?: string
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'app-list-generic-resource',
|
||||
templateUrl: './list-generic-resource.component.html',
|
||||
styleUrls: ['./list-generic-resource.component.scss']
|
||||
})
|
||||
export class ListGenericResourceComponent implements OnInit {
|
||||
|
||||
@Input() resourceList: ResourceFhir[] = []
|
||||
|
||||
// description: string
|
||||
// c: ListGenericResourceComponentColumn[] = []
|
||||
columnDefinitions: GenericColumnDefn[] = []
|
||||
|
||||
// datatable properties (DO NOT CHANGE)
|
||||
@ViewChild(DatatableComponent) table: DatatableComponent;
|
||||
rows = [];
|
||||
columns = []; //{ prop: 'name' }, { name: 'Company' }, { name: 'Gender' }
|
||||
ColumnMode = ColumnMode;
|
||||
|
||||
constructor() {}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.columns = this.columnDefinitions.map((defn) => {
|
||||
let column = {name: defn.title, prop: defn.title.replace(/[^A-Z0-9]/ig, "_")}
|
||||
return column
|
||||
})
|
||||
|
||||
this.rows = this.resourceList.map((resource) => {
|
||||
let row = {}
|
||||
|
||||
this.columnDefinitions.forEach((defn) => {
|
||||
let resourceProp = defn.getter(resource.payload)
|
||||
let resourceFormatted = defn.format ? FORMATTERS[defn.format](resourceProp) : resourceProp
|
||||
row[defn.title.replace(/[^A-Z0-9]/ig, "_")] = resourceFormatted
|
||||
//TODO: handle defaultValue
|
||||
})
|
||||
|
||||
console.log("ROW:", row)
|
||||
|
||||
return row
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
// START OVERRIDES
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
import {Component} from '@angular/core';
|
||||
import {GenericColumnDefn, ListGenericResourceComponent} from './list-generic-resource.component';
|
||||
|
||||
@Component({
|
||||
selector: 'app-list-immunization',
|
||||
templateUrl: './list-generic-resource.component.html',
|
||||
styleUrls: ['./list-generic-resource.component.scss']
|
||||
})
|
||||
export class ListImmunizationComponent extends ListGenericResourceComponent {
|
||||
columnDefinitions: GenericColumnDefn[] = [
|
||||
{ title: 'Vaccine', versions: '*', format: 'code', getter: i => i.vaccineCode.coding[0] },
|
||||
{ title: 'Date Given', versions: '*', format: 'date', getter: i => i.date || i.occurrenceDateTime || i.occurrenceStringe },
|
||||
{ title: 'Date Recorded', versions: '*', format: 'date', getter: i => i.recorded }
|
||||
]
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
import {Component} from '@angular/core';
|
||||
import {GenericColumnDefn, ListGenericResourceComponent} from './list-generic-resource.component';
|
||||
|
||||
@Component({
|
||||
selector: 'app-list-medication-request',
|
||||
templateUrl: './list-generic-resource.component.html',
|
||||
styleUrls: ['./list-generic-resource.component.scss']
|
||||
})
|
||||
export class ListMedicationRequestComponent extends ListGenericResourceComponent {
|
||||
columnDefinitions: GenericColumnDefn[] = [
|
||||
{ title: 'Medication', versions: '*', format: 'code', getter: m => m.medicationCodeableConcept?.coding[0] },
|
||||
{ title: 'Dosage Timing', versions: '*', format: 'period', getter: m => m.dosageInstruction[0]?.timing.repeat.boundsPeriod},
|
||||
{ title: 'Dosage Date', versions: '*', format: 'date', getter: m => m.dosageInstruction[0]?.timing.event},
|
||||
{ title: 'Author Date', versions: '*', format: 'date', getter: m => m.authoredOn },
|
||||
{ title: 'Do Not Perform', versions: '*', getter: m => m.doNotPerform},
|
||||
{ title: 'Reason', versions: '*', format: 'code', getter: m => m.reasonCode[0]?.coding[0] },
|
||||
{ title: 'Route', versions: '*', format: 'code', getter: m => m.dosageInstruction[0]?.route.coding[0] }
|
||||
]
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
import {Component} from '@angular/core';
|
||||
import {GenericColumnDefn, ListGenericResourceComponent} from './list-generic-resource.component';
|
||||
|
||||
@Component({
|
||||
selector: 'app-list-medication',
|
||||
templateUrl: './list-generic-resource.component.html',
|
||||
styleUrls: ['./list-generic-resource.component.scss']
|
||||
})
|
||||
export class ListMedicationComponent extends ListGenericResourceComponent {
|
||||
columnDefinitions: GenericColumnDefn[] = [
|
||||
{ title: 'Medication', versions: '*', format: 'code', getter: c => c.medicationCodeableConcept.coding[0] },
|
||||
{ title: 'Date Prescribed', versions: '*', format: 'date', getter: c => c.authoredOn },
|
||||
{ title: 'Status', 'versions': '*', getter: c => c.status }
|
||||
]
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
import {Component} from '@angular/core';
|
||||
import {attributeXTime, obsValue} from './utils';
|
||||
import {GenericColumnDefn, ListGenericResourceComponent} from './list-generic-resource.component';
|
||||
|
||||
@Component({
|
||||
selector: 'app-list-observation',
|
||||
templateUrl: './list-generic-resource.component.html',
|
||||
styleUrls: ['./list-generic-resource.component.scss']
|
||||
})
|
||||
export class ListObservationComponent extends ListGenericResourceComponent {
|
||||
columnDefinitions: GenericColumnDefn[] = [
|
||||
{ title: 'Observation', versions: '*', format: 'code', getter: o => o.code.coding[0] },
|
||||
{ title: 'Value', versions: '*', getter: o => obsValue(o) },
|
||||
{ title: 'Effective', 'versions': '*', getter: o => attributeXTime(o,'effective') },
|
||||
{ title: 'Issued Date', 'versions': '*', format: 'date', getter: o => o.issued },
|
||||
{ title: 'ID', versions: '*', getter: o => o.id }
|
||||
]
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
import {Component} from '@angular/core';
|
||||
import {attributeXTime} from './utils';
|
||||
import {GenericColumnDefn, ListGenericResourceComponent} from './list-generic-resource.component';
|
||||
|
||||
@Component({
|
||||
selector: 'app-list-procedure',
|
||||
templateUrl: './list-generic-resource.component.html',
|
||||
styleUrls: ['./list-generic-resource.component.scss']
|
||||
})
|
||||
export class ListProcedureComponent extends ListGenericResourceComponent {
|
||||
columnDefinitions: GenericColumnDefn[] = [
|
||||
{ title: 'Procedure', versions: '*', format: 'code', getter: p => p.code.coding[0] },
|
||||
{ title: 'Performed', versions: '*', getter: p => attributeXTime(p,'performed') },
|
||||
{ title: 'ID', versions: '*', getter: p => p.id },
|
||||
{ title: 'Recorded', versions: '*', format: 'dateTime', getter: p => p.extension?.recorded },
|
||||
{ title: 'Reason', versions: '*', format: 'code', getter: p => p.reasonCode?.coding[0] },
|
||||
{ title: 'Status', versions: '*', getter: p => p.status },
|
||||
{ title: 'Status Reason', versions: '*', format: 'code', getter: p => p.statusReason?.coding[0] }
|
||||
]
|
||||
}
|
|
@ -0,0 +1,80 @@
|
|||
import * as moment from 'moment'
|
||||
|
||||
/**
|
||||
* Walks thru an object (ar array) and returns the value found at the provided
|
||||
* path. This function is very simple so it intentionally does not support any
|
||||
* argument polymorphism, meaning that the path can only be a dot-separated
|
||||
* string. If the path is invalid returns undefined.
|
||||
* @param {Object} obj The object (or Array) to walk through
|
||||
* @param {String} path The path (eg. "a.b.4.c")
|
||||
* @returns {*} Whatever is found in the path or undefined
|
||||
*/
|
||||
export function getPath(obj, path = ""): string {
|
||||
return path.split(".").reduce((out, key) => out ? out[key] : undefined, obj)
|
||||
}
|
||||
|
||||
export const FORMATTERS = {
|
||||
date: (str) => str ? moment(str).format('YYYY-MM-DD') : '',
|
||||
time: (str) => str ? moment(str).format('HH:mm:ss') : '',
|
||||
dateTime: (str) => str ? moment(str).format('YYYY-MM-DD - h:mm:ss a') : '',
|
||||
numberWithCommas: (str) => str ? str.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",") : '',
|
||||
code: (code) => code ? `${code.code}: ${code.display ? code.display : ''}` : '',
|
||||
period: (period) => period ? `${moment(period.start).format('YYYY-MM-DD - h:mm:ss a')} -> ${moment(period.end).format('YYYY-MM-DD - h:mm:ss a')}` : ''
|
||||
};
|
||||
|
||||
export function round(num, digits) {
|
||||
return Number.parseFloat(num).toFixed(digits);
|
||||
}
|
||||
|
||||
export function obsValue(entry){
|
||||
if (entry == null) {
|
||||
return '';
|
||||
} else if (entry.valueQuantity) {
|
||||
return round(entry.valueQuantity.value, 2) + ' ' + entry.valueQuantity.code;
|
||||
} else if (entry.valueCodeableConcept) {
|
||||
return entry.valueCodeableConcept.coding[0].display;
|
||||
} else if (entry.valueString) {
|
||||
return entry.valueString;
|
||||
}
|
||||
|
||||
if (entry.code.coding[0].display === "Blood Pressure") {
|
||||
|
||||
if (!entry.component[0].valueQuantity) {
|
||||
return ''; // WTF!!
|
||||
}
|
||||
|
||||
const v1 = Number.parseFloat(entry.component[0].valueQuantity.value);
|
||||
const v2 = Number.parseFloat(entry.component[1].valueQuantity.value);
|
||||
|
||||
const s1 = v1.toFixed(0);
|
||||
const s2 = v2.toFixed(0);
|
||||
|
||||
if (v1 > v2) {
|
||||
return s1 + ' / ' + s2 + ' mmHg';
|
||||
} else {
|
||||
return s2 + ' / ' + s1 + ' mmHg';
|
||||
}
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
export function attributeXTime(entry, type) {
|
||||
if (entry == null) {
|
||||
return '';
|
||||
} else if (entry[`${type}DateTime`]) {
|
||||
return FORMATTERS['dateTime'](entry[`${type}DateTime`])
|
||||
} else if (entry[`${type}Period`]) {
|
||||
return FORMATTERS['period'](entry[`${type}Period`])
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
export function duration(period) {
|
||||
if (!period.end) {
|
||||
return '';
|
||||
}
|
||||
let start = moment(period.start);
|
||||
let end = moment(period.end);
|
||||
return moment.duration( start.diff(end) ).humanize();
|
||||
};
|
|
@ -1,19 +0,0 @@
|
|||
<p class="mg-b-20">A clinical condition, problem, diagnosis, or other event, situation, issue, or clinical concept that has risen to a level of concern.</p>
|
||||
<div class="table-responsive">
|
||||
<table class="table table-bordered mg-b-0">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Type</th>
|
||||
<th>Status</th>
|
||||
<th>Date</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr *ngFor="let immunization of immunizationList">
|
||||
<td>{{immunization.immunizationType}}</td>
|
||||
<td class="align-middle">{{immunization.status || '-'}}</td>
|
||||
<td class="align-middle">{{immunization.date }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
|
@ -1,23 +0,0 @@
|
|||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { ListImmunizationComponent } from './list-immunization.component';
|
||||
|
||||
describe('ListImmunizationComponent', () => {
|
||||
let component: ListImmunizationComponent;
|
||||
let fixture: ComponentFixture<ListImmunizationComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [ ListImmunizationComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(ListImmunizationComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
|
@ -1,26 +0,0 @@
|
|||
import {Component, Input, OnInit} from '@angular/core';
|
||||
import {ResourceFhir} from '../../models/fasten/resource_fhir';
|
||||
import {Encounter} from '../../models/display/encounter';
|
||||
import {Immunization} from '../../models/display/immunization';
|
||||
|
||||
@Component({
|
||||
selector: 'app-list-immunization',
|
||||
templateUrl: './list-immunization.component.html',
|
||||
styleUrls: ['./list-immunization.component.scss']
|
||||
})
|
||||
export class ListImmunizationComponent implements OnInit {
|
||||
|
||||
@Input() resourceList: ResourceFhir[] = []
|
||||
immunizationList: Immunization[] = []
|
||||
|
||||
constructor() { }
|
||||
|
||||
ngOnInit(): void {
|
||||
let _immunizationList = this.immunizationList
|
||||
this.resourceList.forEach((resource) => {
|
||||
let immunization = new Immunization(resource.payload)
|
||||
_immunizationList.push(immunization)
|
||||
})
|
||||
}
|
||||
|
||||
}
|
|
@ -1 +0,0 @@
|
|||
<p>list-observation works!</p>
|
|
@ -1,23 +0,0 @@
|
|||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { ListObservationComponent } from './list-observation.component';
|
||||
|
||||
describe('ListObservationComponent', () => {
|
||||
let component: ListObservationComponent;
|
||||
let fixture: ComponentFixture<ListObservationComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [ ListObservationComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(ListObservationComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
|
@ -1,15 +0,0 @@
|
|||
import { Component, OnInit } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-list-observation',
|
||||
templateUrl: './list-observation.component.html',
|
||||
styleUrls: ['./list-observation.component.scss']
|
||||
})
|
||||
export class ListObservationComponent implements OnInit {
|
||||
|
||||
constructor() { }
|
||||
|
||||
ngOnInit(): void {
|
||||
}
|
||||
|
||||
}
|
|
@ -3,19 +3,25 @@ import { ComponentsSidebarComponent } from './components-sidebar/components-side
|
|||
import { RouterModule } from '@angular/router';
|
||||
import { UtilitiesSidebarComponent } from './utilities-sidebar/utilities-sidebar.component';
|
||||
import { ListPatientComponent } from './list-patient/list-patient.component';
|
||||
import { ListObservationComponent } from './list-observation/list-observation.component';
|
||||
import { ListExplanationOfBenefitComponent } from './list-explanation-of-benefit/list-explanation-of-benefit.component';
|
||||
import { ListImmunizationComponent } from './list-immunization/list-immunization.component';
|
||||
import { ListEncounterComponent } from './list-encounter/list-encounter.component';
|
||||
import { ListConditionComponent } from './list-condition/list-condition.component';
|
||||
import { ListCarePlanComponent } from './list-care-plan/list-care-plan.component';
|
||||
import {BrowserModule} from '@angular/platform-browser';
|
||||
import { ListGenericResourceComponent } from './list-generic-resource/list-generic-resource.component';
|
||||
import { ListGenericResourceComponent,} from './list-generic-resource/list-generic-resource.component';
|
||||
import {ListConditionComponent} from './list-generic-resource/list-condition.component'
|
||||
import {ListEncounterComponent} from './list-generic-resource/list-encounter.component'
|
||||
import {ListMedicationComponent} from './list-generic-resource/list-medication.component'
|
||||
import {ListObservationComponent} from './list-generic-resource/list-observation.component'
|
||||
import {ListProcedureComponent} from './list-generic-resource/list-procedure.component'
|
||||
import {ListImmunizationComponent} from './list-generic-resource/list-immunization.component'
|
||||
import {ListMedicationRequestComponent} from './list-generic-resource/list-medication-request.component'
|
||||
|
||||
import { NgxDatatableModule } from '@swimlane/ngx-datatable';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
RouterModule,
|
||||
BrowserModule,
|
||||
NgxDatatableModule
|
||||
],
|
||||
declarations: [
|
||||
ComponentsSidebarComponent,
|
||||
|
@ -25,20 +31,28 @@ import { ListGenericResourceComponent } from './list-generic-resource/list-gener
|
|||
ListExplanationOfBenefitComponent,
|
||||
ListImmunizationComponent,
|
||||
ListEncounterComponent,
|
||||
ListConditionComponent,
|
||||
ListCarePlanComponent,
|
||||
ListGenericResourceComponent
|
||||
ListGenericResourceComponent,
|
||||
ListMedicationComponent,
|
||||
ListProcedureComponent,
|
||||
ListConditionComponent,
|
||||
ListMedicationRequestComponent
|
||||
],
|
||||
exports: [
|
||||
ComponentsSidebarComponent,
|
||||
UtilitiesSidebarComponent,
|
||||
ListPatientComponent,
|
||||
ListObservationComponent,
|
||||
ListExplanationOfBenefitComponent,
|
||||
ListImmunizationComponent,
|
||||
ListEncounterComponent,
|
||||
ListCarePlanComponent,
|
||||
ListGenericResourceComponent,
|
||||
ListMedicationComponent,
|
||||
ListObservationComponent,
|
||||
ListProcedureComponent,
|
||||
ListConditionComponent,
|
||||
ListCarePlanComponent
|
||||
ListMedicationRequestComponent
|
||||
|
||||
]
|
||||
})
|
||||
|
||||
|
|
|
@ -1,45 +0,0 @@
|
|||
import {getCodeOrConcept} from '../../fhir/utils';
|
||||
import {CODE_SYSTEMS} from '../../fhir/constants';
|
||||
|
||||
export class Condition {
|
||||
name: string
|
||||
nameCode: string
|
||||
nameCodeSystem: string
|
||||
clinicalStatus: string
|
||||
verificationStatus: string
|
||||
onset: string
|
||||
|
||||
constructor(resourcePayload: any) {
|
||||
this.populateConditionName(resourcePayload)
|
||||
this.clinicalStatus = getCodeOrConcept(resourcePayload.clinicalStatus)
|
||||
this.verificationStatus = getCodeOrConcept(resourcePayload.verificationStatus)
|
||||
this.onset = resourcePayload.onsetDateTime
|
||||
}
|
||||
|
||||
populateConditionName(resourePayload: any){
|
||||
if (resourePayload.code) {
|
||||
if (resourePayload.code.text) {
|
||||
this.name = resourePayload.code.text;
|
||||
}
|
||||
if (Array.isArray(resourePayload.code.coding) && resourePayload.code.coding.length) {
|
||||
let c = resourePayload.code.coding[0]
|
||||
|
||||
this.nameCodeSystem = c.system
|
||||
for (let key in CODE_SYSTEMS) {
|
||||
if (CODE_SYSTEMS[key].url === c.system) {
|
||||
this.nameCodeSystem = `(${key})`;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (c.display) {
|
||||
this.name = c.display
|
||||
}
|
||||
if (c.code) {
|
||||
this.nameCode = c.code
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,14 +0,0 @@
|
|||
import {getPath} from '../../fhir/utils';
|
||||
import * as moment from 'moment'
|
||||
|
||||
export class Immunization {
|
||||
immunizationType: string
|
||||
status: string
|
||||
date: moment.Moment
|
||||
|
||||
constructor(resourcePayload: any) {
|
||||
this.immunizationType = getPath(resourcePayload, "vaccineCode.coding.0.display")
|
||||
this.status = resourcePayload.status || "-"
|
||||
this.date = moment(resourcePayload.date || resourcePayload.occurrenceDateTime || resourcePayload.occurrenceString)
|
||||
}
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
import * as moment from 'moment';
|
||||
import {getPath} from '../../fhir/utils';
|
||||
|
||||
export class Observation {
|
||||
code: string
|
||||
status: string
|
||||
date: moment.Moment
|
||||
|
||||
// { title: 'Observation', versions: '*', format: 'code', getter: o => o.code.coding[0] },
|
||||
// { title: 'Value', versions: '*', getter: o => obsValue(o) },
|
||||
// { title: 'Effective', 'versions': '*', getter: o => attributeXTime(o,'effective') },
|
||||
// { title: 'Issued Date', 'versions': '*', format: 'date', getter: o => o.issued },
|
||||
// { title: 'ID', versions: '*', getter: o => o.id }
|
||||
|
||||
constructor(resourcePayload: any) {
|
||||
this.code = getPath(resourcePayload, "code.coding[0].display")
|
||||
this.status = resourcePayload.status || "-"
|
||||
this.date = moment(resourcePayload.date || resourcePayload.occurrenceDateTime || resourcePayload.occurrenceString)
|
||||
}
|
||||
}
|
|
@ -20,7 +20,10 @@
|
|||
<app-list-care-plan *ngIf="selectedResourceType == 'CarePlan'" [resourceList]="selectedResources"></app-list-care-plan>
|
||||
<app-list-encounter *ngIf="selectedResourceType == 'Encounter'" [resourceList]="selectedResources"></app-list-encounter>
|
||||
<app-list-immunization *ngIf="selectedResourceType == 'Immunization'" [resourceList]="selectedResources"></app-list-immunization>
|
||||
|
||||
<app-list-medication *ngIf="selectedResourceType == 'Medication'" [resourceList]="selectedResources"></app-list-medication>
|
||||
<app-list-medication-request *ngIf="selectedResourceType == 'MedicationRequest'" [resourceList]="selectedResources"></app-list-medication-request>
|
||||
<app-list-observation *ngIf="selectedResourceType == 'Observation'" [resourceList]="selectedResources"></app-list-observation>
|
||||
<app-list-procedure *ngIf="selectedResourceType == 'Procedure'" [resourceList]="selectedResources"></app-list-procedure>
|
||||
|
||||
</div><!-- az-content-body -->
|
||||
</div><!-- container -->
|
||||
|
|
|
@ -206,3 +206,7 @@
|
|||
//@import "~datatables.net-dt/css/jquery.dataTables.css";
|
||||
//@import '~@fullcalendar/core/main.css';
|
||||
//@import '~perfect-scrollbar/css/perfect-scrollbar.css';
|
||||
|
||||
@import '~@swimlane/ngx-datatable/index.css';
|
||||
@import '~@swimlane/ngx-datatable/themes/bootstrap.css';
|
||||
@import '~@swimlane/ngx-datatable/assets/icons.css';
|
||||
|
|
Loading…
Reference in New Issue