From b99b3b527ac92e59b3b69b7f6a22ab4e5045e634 Mon Sep 17 00:00:00 2001 From: John Grimes Date: Wed, 25 Aug 2021 11:09:32 +1000 Subject: [PATCH 1/2] Initial implementation of FHIR value set import --- js/components/conceptset/import.js | 9 +++- js/components/conceptset/import/fhir.html | 18 ++++++++ js/components/conceptset/import/fhir.js | 51 +++++++++++++++++++++++ 3 files changed, 77 insertions(+), 1 deletion(-) create mode 100644 js/components/conceptset/import/fhir.html create mode 100644 js/components/conceptset/import/fhir.js diff --git a/js/components/conceptset/import.js b/js/components/conceptset/import.js index 623aae4ce..40c2778e2 100644 --- a/js/components/conceptset/import.js +++ b/js/components/conceptset/import.js @@ -12,6 +12,7 @@ define([ './import/identifiers', './import/sourcecodes', './import/conceptset', + './import/fhir', ],function( ko, view, @@ -60,6 +61,12 @@ define([ { title: ko.i18n('components.conceptSet.repository', 'Repository'), key: 'repository', + }, + { + title: ko.i18n('components.conceptSet.fhir', 'FHIR'), + key: 'fhir', + componentName: 'conceptset-list-import-fhir', + componentParams: {...params, appendConcepts: this.appendConcepts} } ]; } @@ -125,4 +132,4 @@ define([ } return commonUtils.build('conceptset-list-import', ConceptSetImport, view); -}); \ No newline at end of file +}); diff --git a/js/components/conceptset/import/fhir.html b/js/components/conceptset/import/fhir.html new file mode 100644 index 000000000..395248933 --- /dev/null +++ b/js/components/conceptset/import/fhir.html @@ -0,0 +1,18 @@ +
+
+ +
+ + + +
+
diff --git a/js/components/conceptset/import/fhir.js b/js/components/conceptset/import/fhir.js new file mode 100644 index 000000000..89721292e --- /dev/null +++ b/js/components/conceptset/import/fhir.js @@ -0,0 +1,51 @@ +define([ + 'knockout', + 'text!./fhir.html', + 'components/Component', + './ImportComponent', + 'utils/AutoBind', + 'utils/Clipboard', + 'utils/CommonUtils', + 'services/VocabularyProvider', + 'services/http', + 'atlas-state', +], function( + ko, + view, + Component, + ImportComponent, + AutoBind, + Clipboard, + commonUtils, + vocabularyApi, + httpService, + sharedState, +){ + + class FhirImport extends AutoBind(ImportComponent(Component)) { + constructor(params) { + super(params); + this.fhirServer = ko.observable("https://r4.ontoserver.csiro.au/fhir"); + this.valueSet = ko.observable(""); + this.appendConcepts = params.appendConcepts; + this.canAddConcepts = ko.pureComputed(() => + this.fhirServer().length > 0 && + this.valueSet().length > 0 && + params.canEdit() + ); + this.doImport = this.doImport.bind(this); + } + + async runImport(options) { + const expandUrl = `${this.fhirServer()}/ValueSet/$expand`, + expandParams = { + url: this.valueSet() + }, result = await httpService.doGet(expandUrl, expandParams), + codes = result.data.expansion.contains.map(c => c.code), + {data} = await vocabularyApi.getConceptsByCode(codes); + this.appendConcepts(data, options); + } + } + + return commonUtils.build('conceptset-list-import-fhir', FhirImport, view); +}); From 4b5fe4c83cd09951ad50feca0165547dfabf4cf5 Mon Sep 17 00:00:00 2001 From: John Grimes Date: Mon, 6 Sep 2021 13:38:16 +1000 Subject: [PATCH 2/2] Move terminology server URL out to config, and set Accept header --- js/components/conceptset/import/fhir.js | 8 ++++---- js/config/app.js | 2 ++ js/services/http.js | 17 ++++++++++++++++- 3 files changed, 22 insertions(+), 5 deletions(-) diff --git a/js/components/conceptset/import/fhir.js b/js/components/conceptset/import/fhir.js index 89721292e..d639cf916 100644 --- a/js/components/conceptset/import/fhir.js +++ b/js/components/conceptset/import/fhir.js @@ -8,7 +8,7 @@ define([ 'utils/CommonUtils', 'services/VocabularyProvider', 'services/http', - 'atlas-state', + 'appConfig', ], function( ko, view, @@ -19,13 +19,13 @@ define([ commonUtils, vocabularyApi, httpService, - sharedState, + config ){ class FhirImport extends AutoBind(ImportComponent(Component)) { constructor(params) { super(params); - this.fhirServer = ko.observable("https://r4.ontoserver.csiro.au/fhir"); + this.fhirServer = ko.observable(config.fhirTerminologyUrl); this.valueSet = ko.observable(""); this.appendConcepts = params.appendConcepts; this.canAddConcepts = ko.pureComputed(() => @@ -40,7 +40,7 @@ define([ const expandUrl = `${this.fhirServer()}/ValueSet/$expand`, expandParams = { url: this.valueSet() - }, result = await httpService.doGet(expandUrl, expandParams), + }, result = await httpService.fhirService.doGet(expandUrl, expandParams), codes = result.data.expansion.contains.map(c => c.code), {data} = await vocabularyApi.getConceptsByCode(codes); this.appendConcepts(data, options); diff --git a/js/config/app.js b/js/config/app.js index 672c8f8e4..bfbccb574 100644 --- a/js/config/app.js +++ b/js/config/app.js @@ -151,5 +151,7 @@ define(function () { } }; + appConfig.fhirTerminologyUrl = "https://r4.ontoserver.csiro.au/fhir"; + return appConfig; }); diff --git a/js/services/http.js b/js/services/http.js index 2b6cc2c3f..f009803ca 100644 --- a/js/services/http.js +++ b/js/services/http.js @@ -3,7 +3,7 @@ define(function(require, exports) { const config = require('appConfig'); const sharedState = require('atlas-state'); const { Api:OHDSIApi, STATUS } = require('ohdsi-api'); - const JSON_RESPONSE_TYPE = 'application/json'; + const FHIR_JSON_RESPONSE_TYPE = 'application/fhir+json'; const TEXT_RESPONSE_TYPE = 'text/plain'; const EventBus = require('services/EventBus'); @@ -100,6 +100,18 @@ define(function(require, exports) { } } + class FhirApi extends Api { + getHeaders(requestUrl) { + return { + 'Accept': FHIR_JSON_RESPONSE_TYPE, + }; + } + + parseResponse(json) { + return JSON.parse(json); + } + } + const singletonApi = new Api(); singletonApi.setAuthTokenHeader('Authorization'); @@ -108,7 +120,10 @@ define(function(require, exports) { plainTextService.setUnauthorizedHandler(() => singletonApi.handleUnauthorized()); plainTextService.setUserTokenGetter(() => singletonApi.getUserToken()); + const fhirService = new FhirApi(); + singletonApi.plainTextService = plainTextService; + singletonApi.fhirService = fhirService; return singletonApi; });