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..d639cf916 --- /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', + 'appConfig', +], function( + ko, + view, + Component, + ImportComponent, + AutoBind, + Clipboard, + commonUtils, + vocabularyApi, + httpService, + config +){ + + class FhirImport extends AutoBind(ImportComponent(Component)) { + constructor(params) { + super(params); + this.fhirServer = ko.observable(config.fhirTerminologyUrl); + 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.fhirService.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); +}); 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; });