diff --git a/README.md b/README.md
index bf90d4b..9cd7e2b 100644
--- a/README.md
+++ b/README.md
@@ -20,3 +20,15 @@ To run these demos locally:
`ng serve`
Navigate to `http://localhost:4200/`. The application will automatically reload if you change any of the source files.
+
+## Regional specific configuration
+
+Some regions may have specific requirements and additional configuration - this configuration needs to be specified when running `ng serve`
+
+These configuration files are at at `src/environments` and applies to various components within the SCT Demonstrator application.
+
+Run:
+`ng serve --configuration=some-region`
+
+Note: Adding new regional config must have an accompanying configuration section for both `build` and `serve` in `angular.json`.
+
diff --git a/angular.json b/angular.json
index 3aa290e..fed6f28 100644
--- a/angular.json
+++ b/angular.json
@@ -93,6 +93,33 @@
"extractLicenses": false,
"sourceMap": true,
"namedChunks": true
+ },
+ "australia": {
+ "baseHref": "/",
+ "budgets": [
+ {
+ "type": "initial",
+ "maximumWarning": "10mb",
+ "maximumError": "10mb"
+ },
+ {
+ "type": "anyComponentStyle",
+ "maximumWarning": "500kb",
+ "maximumError": "999kb"
+ }
+ ],
+ "outputHashing": "all",
+ "optimization": {
+ "scripts": true,
+ "styles": true,
+ "fonts": false
+ },
+ "fileReplacements": [
+ {
+ "replace": "src/environments/environment.ts",
+ "with": "src/environments/environment.australia.ts"
+ }
+ ]
}
},
"defaultConfiguration": "production"
@@ -101,9 +128,13 @@
"builder": "@angular-devkit/build-angular:dev-server",
"configurations": {
"production": {
+ "buildTarget": "sct-implementation-demonstrator:build:production"
},
"development": {
"buildTarget": "sct-implementation-demonstrator:build:development"
+ },
+ "australia": {
+ "buildTarget": "sct-implementation-demonstrator:build:australia"
}
},
"defaultConfiguration": "development"
diff --git a/docs/assets/language/national-language-metadata.json b/docs/assets/language/national-language-metadata.json
index 7d154fb..7d129f5 100644
--- a/docs/assets/language/national-language-metadata.json
+++ b/docs/assets/language/national-language-metadata.json
@@ -111,6 +111,23 @@
"languageDialects": "sv-X-83461000052100,sv-X-46011000052107,en-X-900000000000509007"
}
]
+ },
+ {
+ "title": "Australian Edition",
+ "moduleUri": "http://snomed.info/sct/32506021000036107",
+ "languageCodes": [
+ "en"
+ ],
+ "languageRefsets": [
+ "32570271000036106"
+ ],
+ "contexts": [
+ {
+ "name": "Australian English",
+ "languageDialects": "en-X-sctlang-32570271-00003610-6"
+ }
+
+ ]
}
]
}
\ No newline at end of file
diff --git a/src/app/allergies/allergies-allergy-list/allergies-allergy-list-reaction/allergies-allergy-list-reaction.component.html b/src/app/allergies/allergies-allergy-list/allergies-allergy-list-reaction/allergies-allergy-list-reaction.component.html
index b3a6a6c..89d06fc 100644
--- a/src/app/allergies/allergies-allergy-list/allergies-allergy-list-reaction/allergies-allergy-list-reaction.component.html
+++ b/src/app/allergies/allergies-allergy-list/allergies-allergy-list-reaction/allergies-allergy-list-reaction.component.html
@@ -24,19 +24,22 @@
{{option.display}}
-
-
diff --git a/src/app/allergies/allergies-allergy-list/allergies-allergy-list-reaction/allergies-allergy-list-reaction.component.ts b/src/app/allergies/allergies-allergy-list/allergies-allergy-list-reaction/allergies-allergy-list-reaction.component.ts
index db50f24..71d1ec0 100644
--- a/src/app/allergies/allergies-allergy-list/allergies-allergy-list-reaction/allergies-allergy-list-reaction.component.ts
+++ b/src/app/allergies/allergies-allergy-list/allergies-allergy-list-reaction/allergies-allergy-list-reaction.component.ts
@@ -1,6 +1,8 @@
import { Component, EventEmitter, Input, Output, forwardRef } from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
+import { environment } from '../../../../environments/environment';
+
@Component({
selector: 'app-allergies-allergy-list-reaction',
templateUrl: './allergies-allergy-list-reaction.component.html',
@@ -21,14 +23,17 @@ export class AllergiesAllergyListReactionComponent implements ControlValueAccess
// add emitter for new problem
@Output() newManifestation = new EventEmitter
();
+ //config
+ showExposureRoute = environment.allergyList.enableExposureRoute;
+
severityOptions = [
{ code: 'mild', display: 'Mild', sctCode: '255604002', sctDisplay: 'Mild (qualifier value)' },
{ code: 'moderate', display: 'Moderate', sctCode: '6736007', sctDisplay: 'Moderate (qualifier value)' },
{ code: 'severe', display: 'Severe', sctCode: '24484000', sctDisplay: 'Severe (qualifier value)' }
];
selectedSeverity: any = {};
- reactionManifestationBinding = { ecl: '<<404684003 |Clinical finding|', title: 'Reaction Manifestation' };
- routeBinding = { ecl: '<<284009009 |Route of administration value|', title: 'Exposure Route' };
+ reactionManifestationBinding = environment.allergyList.reactionManifestationBinding;
+ routeBinding = environment.allergyList.routeBinding;
reaction: any = {};
diff --git a/src/app/allergies/allergies-allergy-list/allergies-allergy-list.component.html b/src/app/allergies/allergies-allergy-list/allergies-allergy-list.component.html
index b5eb1a4..7b583a4 100644
--- a/src/app/allergies/allergies-allergy-list/allergies-allergy-list.component.html
+++ b/src/app/allergies/allergies-allergy-list/allergies-allergy-list.component.html
@@ -36,8 +36,16 @@ Allergy list
+
+
+
+ Patient Reference
+
+
+
+
-
@@ -106,6 +114,14 @@
Allergy list
+
+
+
+ Notes
+
+
+
+
diff --git a/src/app/allergies/allergies-allergy-list/allergies-allergy-list.component.ts b/src/app/allergies/allergies-allergy-list/allergies-allergy-list.component.ts
index aaa991e..c0eaa1f 100644
--- a/src/app/allergies/allergies-allergy-list/allergies-allergy-list.component.ts
+++ b/src/app/allergies/allergies-allergy-list/allergies-allergy-list.component.ts
@@ -7,6 +7,9 @@ import { saveAs } from 'file-saver';
import { Clipboard } from '@angular/cdk/clipboard';
import { MatSnackBar } from '@angular/material/snack-bar';
import { SnackAlertComponent } from 'src/app/alerts/snack-alert';
+
+import { environment } from '../../../environments/environment';
+
@Component({
selector: 'app-allergies-allergy-list',
templateUrl: './allergies-allergy-list.component.html',
@@ -17,6 +20,11 @@ export class AllergiesAllergyListComponent implements OnInit {
@Output() newProblem = new EventEmitter
();
+ //config
+ showNotes = environment.allergyList.enableNotes;
+ showPropensity = environment.allergyList.enablePropensity;
+ showPatient = environment.allergyList.enablePatient;
+
clinicalStatusOptions = [
{ system: "http://terminology.hl7.org/CodeSystem/allergyintolerance-clinical", code: 'active', display: 'Active' },
{ system: "http://terminology.hl7.org/CodeSystem/allergyintolerance-clinical", code: 'inactive', display: 'Inactive' },
@@ -62,13 +70,13 @@ export class AllergiesAllergyListComponent implements OnInit {
];
selectedSeverity: any = {};
- codeBinding = { ecl: '<<418038007 |Propensity to adverse reactions to substance| OR <<420134006 |Propensity to adverse reaction (finding)|', title: 'Allergy/Intolerance by propensity' };
+ codeBinding = environment.allergyList.codeBinding;
selectedCode: any = null;
selectedCodeTerm = "";
recordPropensity = false;
- substanceBinding = { ecl: '<<105590001 | Substance (substance) | OR <<373873005 | Pharmaceutical / biologic product (product) |', title: 'Allergy/Intolerance substance or product' };
- refinedSubstanceBinding = { ecl: '<<105590001 | Substance (substance) |', title: 'Allergy/Intolerance substance based on propensity' };
+ substanceBinding = environment.allergyList.substanceBinding;
+ refinedSubstanceBinding = environment.allergyList.refinedSubstanceBinding;
selectedSubstanceTerm = "";
selectedSubstance: any = null;
@@ -81,13 +89,17 @@ export class AllergiesAllergyListComponent implements OnInit {
}
];
- reactionManifestationBinding = { ecl: '<<404684003 |Clinical finding|', title: 'Reaction Manifestation' };
selectedReactionManifestation: any = null;
selectedReactionManifestationTerm = "";
- routeBinding = { ecl: '<<284009009 |Route of administration value|', title: 'Exposure Route' };
+
selectedRoute: any = null;
selectedRouteTerm = "";
+ notes: any[] = [];
+ noteText: string = "";
+
+ patientReference: string = "";
+
outputAllergyBase: any = {
"resourceType" : "AllergyIntolerance",
"id" : "medication",
@@ -117,7 +129,7 @@ export class AllergiesAllergyListComponent implements OnInit {
"severity" : ""
}],
"patient" : {
- "reference" : "Patient/example"
+ "reference" : ""
},
"recordedDate" : "2010-03-01",
"participant" : [{
@@ -131,7 +143,11 @@ export class AllergiesAllergyListComponent implements OnInit {
"actor" : {
"reference" : "Practitioner/example"
}
- }]
+ }],
+ "note": [{
+ "text": ""
+ }
+ ],
}
outputAllergy: any = JSON.parse(JSON.stringify(this.outputAllergyBase));
@@ -173,6 +189,9 @@ export class AllergiesAllergyListComponent implements OnInit {
route: {}
}
];
+ this.notes = [];
+ this.noteText = "";
+ this.patientReference
this.outputAllergy = JSON.parse(JSON.stringify(this.outputAllergyBase));
this.updateAllergyStr();
setTimeout(() => {
@@ -190,8 +209,8 @@ export class AllergiesAllergyListComponent implements OnInit {
this.outputAllergy.criticality = (this.selectedCriticality?.code) ? [this.selectedCriticality.code] : {};
this.outputAllergy.reaction = [];
this.selectedReactions.forEach((reaction: any) => {
- if (reaction.manifestation.code) { reaction.manifestation.system = 'http://snomed.info/sct'; }
- if (reaction.route.code) { reaction.route.system = 'http://snomed.info/sct'; }
+ if (reaction.manifestation && reaction.manifestation.code) { reaction.manifestation.system = 'http://snomed.info/sct'; }
+ if (reaction.route && reaction.route.code) { reaction.route.system = 'http://snomed.info/sct'; }
const newReaction = {
substance: [{
coding: [this.selectedSubstance]
@@ -206,6 +225,15 @@ export class AllergiesAllergyListComponent implements OnInit {
};
this.outputAllergy.reaction.push(newReaction);
});
+
+ // Update notes array from noteText
+ this.notes = this.noteText && this.noteText.trim() !== ''
+ ? [{ text: this.noteText }]
+ : [];
+ this.outputAllergy.note = [...this.notes];
+
+ this.outputAllergy.patient.reference = this.patientReference.trim() ? this.patientReference : '';
+
setTimeout(() => {
this.outputAllergyStr = JSON.stringify(this.outputAllergy, null, 2);
}
diff --git a/src/app/app.component.ts b/src/app/app.component.ts
index 89f8376..61417d4 100644
--- a/src/app/app.component.ts
+++ b/src/app/app.component.ts
@@ -9,6 +9,8 @@ import { LanguageConfigComponent } from './util/language-config/language-config.
import { catchError, of, skip, Subject, switchMap, tap } from 'rxjs';
import { HttpClient } from '@angular/common/http';
+import { environment } from '../environments/environment';
+
declare let gtag: Function;
@Component({
@@ -41,7 +43,7 @@ export class AppComponent {
{ name: "SNOMED Dev 1", url: "https://dev-browser.ihtsdotools.org/fhir"},
{ name: "Implementation Demo", url: "https://implementation-demo.snomedtools.org/fhir"},
];
- selectedServer = this.fhirServers[1];
+ selectedServer = this.fhirServers[environment.defaultFhirServerIndex];
embeddedMode: boolean = false;
demos: any[] = [];
@@ -163,18 +165,20 @@ export class AppComponent {
}
});
+ // Set default server from config
+ this.setFhirServer(this.fhirServers[environment.defaultFhirServerIndex]);
+
+ // now subscribe to changes
this.terminologyService.snowstormFhirBase$.subscribe(url => {
if (this.fhirServers?.length > 0) {
- this.fhirServers.forEach(loopServer => {
- if (loopServer.url === url) {
- this.selectedServer = loopServer;
- this.cdRef.detectChanges();
- this.updateCodeSystemOptions()
- }
- });
+ const found = this.fhirServers.find(server => server.url === url);
+ if (found) {
+ this.selectedServer = found;
+ this.cdRef.detectChanges();
+ this.updateCodeSystemOptions();
+ }
}
});
- this.setFhirServer(this.selectedServer);
// this.http.get('https://raw.githubusercontent.com/IHTSDO/snomedct-language-metadata/refs/heads/main/national-language-metadata.json').subscribe((data: any) => {
// this.languageMetadata = data;
@@ -188,7 +192,7 @@ export class AppComponent {
setupLanguageMetadata() {
let editionUri = this.terminologyService.getFhirUrlParam();
- // Remve the verssion data from the editionUri (http://snomed.info/sct/900000000000207008/version/20250501 to http://snomed.info/sct/900000000000207008)
+ // Remove the version data from the editionUri (http://snomed.info/sct/900000000000207008/version/20250501 to http://snomed.info/sct/900000000000207008)
if (editionUri.includes('/version/')) {
const editionUriParts = editionUri.split('/');
editionUriParts.pop();
@@ -200,6 +204,8 @@ export class AppComponent {
if (!this.filteredLanguageMetadata) {
this.filteredLanguageMetadata = { contexts: [] };
}
+
+ //Fallback to US English if not found
this.filteredLanguageMetadata.contexts.push({ name: 'US English', languageDialects: 'en-X-900000000000509007' });
this.setContext(this.filteredLanguageMetadata.contexts[0]);
diff --git a/src/app/services/terminology.service.ts b/src/app/services/terminology.service.ts
index a594428..bf046e1 100644
--- a/src/app/services/terminology.service.ts
+++ b/src/app/services/terminology.service.ts
@@ -135,10 +135,20 @@ export class TerminologyService {
if (this.context) {
return this.context.languageDialects;
} else if (this.languageRefsetConcept) {
- return this.lang + '-X-' + this.languageRefsetConcept.code
+ return this.toLanguageCode(this.lang, this.languageRefsetConcept.code);
} else return this.lang;
}
+ toLanguageCode(lang: string, langRefset: string) {
+ if (langRefset.length > 16) {
+ return `${lang}-x-sctlang-${langRefset.substring(0, 8)}-${langRefset.substring(8, 16)}-${langRefset.substring(16)}`;
+ } else if (langRefset.length > 8) {
+ return `${lang}-x-sctlang-${langRefset.substring(0, 8)}-${langRefset.substring(8)}`;
+ } else {
+ return `${lang}-x-sctlang-${langRefset}`;
+ }
+ }
+
getCodeSystems() {
let requestUrl = `${this.snowstormFhirBase}/CodeSystem`;
if (this.snowstormFhirBase.includes('ontoserver')) {
diff --git a/src/assets/language/national-language-metadata.json b/src/assets/language/national-language-metadata.json
index 7d154fb..7d129f5 100644
--- a/src/assets/language/national-language-metadata.json
+++ b/src/assets/language/national-language-metadata.json
@@ -111,6 +111,23 @@
"languageDialects": "sv-X-83461000052100,sv-X-46011000052107,en-X-900000000000509007"
}
]
+ },
+ {
+ "title": "Australian Edition",
+ "moduleUri": "http://snomed.info/sct/32506021000036107",
+ "languageCodes": [
+ "en"
+ ],
+ "languageRefsets": [
+ "32570271000036106"
+ ],
+ "contexts": [
+ {
+ "name": "Australian English",
+ "languageDialects": "en-X-sctlang-32570271-00003610-6"
+ }
+
+ ]
}
]
}
\ No newline at end of file
diff --git a/src/environments/environment.australia.ts b/src/environments/environment.australia.ts
new file mode 100644
index 0000000..7992946
--- /dev/null
+++ b/src/environments/environment.australia.ts
@@ -0,0 +1,33 @@
+export const environment = {
+ production: false,
+ country: 'australia',
+ defaultFhirServerIndex: 5,
+
+ allergyList: {
+ enableNotes: true,
+ enablePropensity: false,
+ enablePatient: true,
+ enableExposureRoute: false,
+
+ codeBinding: {
+ ecl: '<<418038007 |Propensity to adverse reactions to substance| OR <<420134006 |Propensity to adverse reaction (finding)|',
+ title: 'Allergy/Intolerance by propensity'
+ },
+ substanceBinding: {
+ ecl: '<<105590001 | Substance (substance) | OR <<373873005 | Pharmaceutical / biologic product (product) |',
+ title: 'Allergy/Intolerance substance or product'
+ },
+ refinedSubstanceBinding: {
+ ecl: '<<105590001 | Substance (substance) |',
+ title: 'Allergy/Intolerance substance based on propensity'
+ },
+ reactionManifestationBinding: {
+ ecl: '<<404684003 | Clinical finding |',
+ title: 'Reaction Manifestation'
+ },
+ routeBinding: {
+ ecl: '<<284009009 | Route of administration value |',
+ title: 'Exposure Route'
+ }
+ }
+};
\ No newline at end of file
diff --git a/src/environments/environment.ts b/src/environments/environment.ts
new file mode 100644
index 0000000..693bd41
--- /dev/null
+++ b/src/environments/environment.ts
@@ -0,0 +1,34 @@
+export const environment = {
+ production: false,
+ country: 'default',
+ defaultFhirServerIndex: 1,
+
+ allergyList: {
+ enableNotes: false,
+ enablePropensity: true,
+ enablePatient: false,
+ enableExposureRoute: true,
+
+ codeBinding: {
+ ecl: '<<418038007 |Propensity to adverse reactions to substance| OR <<420134006 |Propensity to adverse reaction (finding)|',
+ title: 'Allergy/Intolerance by propensity'
+ },
+ substanceBinding: {
+ ecl: '<<105590001 | Substance (substance) | OR <<373873005 | Pharmaceutical / biologic product (product) |',
+ title: 'Allergy/Intolerance substance or product'
+ },
+ refinedSubstanceBinding: {
+ ecl: '<<105590001 | Substance (substance) |',
+ title: 'Allergy/Intolerance substance based on propensity'
+ },
+ reactionManifestationBinding: {
+ ecl: '<<404684003 | Clinical finding |',
+ title: 'Reaction Manifestation'
+ },
+ routeBinding: {
+ ecl: '<<284009009 | Route of administration value |',
+ title: 'Exposure Route'
+ }
+
+ }
+};
\ No newline at end of file