Skip to content

Commit

Permalink
Merge pull request #32 from fair4health/v1.1.1
Browse files Browse the repository at this point in the history
V1.1.1
  • Loading branch information
sinaci authored Jun 17, 2021
2 parents 2c37011 + f5f3f70 commit 97099a2
Show file tree
Hide file tree
Showing 25 changed files with 1,093 additions and 330 deletions.
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "fair4health-data-privacy-tool",
"productName": "FAIR4Health Privacy Tool",
"version": "1.1.0",
"version": "1.1.1",
"private": true,
"author": "SRDC Corporation <[email protected]>",
"description": "FAIR4Health | Data Privacy Tool",
Expand Down
34 changes: 16 additions & 18 deletions src/common/services/deidentification.service.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import {FhirService} from '@/common/services/fhir.service';
import {environment} from '@/common/environment';
import RandExp from 'randexp';
import moment from 'moment-timezone';
import {Utils} from '@/common/utils/util';
import Vue from 'vue';

export class DeidentificationService {
fhirService: FhirService;
typeMappings: any;
parameterMappings: any;
rareValueMappings: any;
Expand All @@ -18,8 +17,13 @@ export class DeidentificationService {
canBeAnonymizedMore: boolean;
anonymizedData;

constructor (typeMappings: any, parameterMappings: any, rareValueMappings: any, requiredElements: string[]) {
this.fhirService = new FhirService(true);
constructor (typeMappings?: any, parameterMappings?: any, rareValueMappings?: any, requiredElements?: string[]) {
if (typeMappings && parameterMappings && rareValueMappings && requiredElements) {
this.init({typeMappings, parameterMappings, rareValueMappings, requiredElements});
}
}

init ({typeMappings, parameterMappings, rareValueMappings, requiredElements}) {
this.typeMappings = JSON.parse(JSON.stringify(typeMappings));
this.parameterMappings = JSON.parse(JSON.stringify(parameterMappings));
this.rareValueMappings = JSON.parse(JSON.stringify(rareValueMappings));
Expand All @@ -32,21 +36,15 @@ export class DeidentificationService {
this.canBeAnonymizedMore = true;
}

getEntries (resource: string, profile: string): Promise<any> {
getEntries (resource: string, profile?: string, profileURL?: string): Promise<any> {
return new Promise((resolve, reject) => {
this.fhirService.search('StructureDefinition',
{_summary: 'data', base: `${environment.hl7}/StructureDefinition/${resource}`}, true)
.then(res => {
let query = {};
if (resource !== profile) { // Not a Base Profile
const url = res.data.entry.find(item => item.resource.id === profile).resource.url;
query = {_profile: url};
}
this.fhirService.search(resource, query, true)
.then(response => {
resolve({resource, profile, entries: response.data.entry});
})
.catch(err => reject(err))
let query = {};
if (profileURL) {
query = {_profile: profileURL};
}
Vue.prototype.$sourceFhirService.search(resource, query, true)
.then(response => {
resolve({resource, profile, entries: response.data.entry});
})
.catch(err => reject(err))
})
Expand Down
20 changes: 7 additions & 13 deletions src/common/services/evaluation.service.ts
Original file line number Diff line number Diff line change
@@ -1,27 +1,21 @@
import {FhirService} from '@/common/services/fhir.service';
import {Utils} from '@/common/utils/util';
import {environment} from '@/common/environment';
import Vue from 'vue'
import {FhirService} from '@/common/services/fhir.service'

export class EvaluationService {
sourceFhirService: FhirService;
targetFhirService: FhirService;
quasis: string[][];
riskyQuasis: string[];
savedResourceNumber = 0;

constructor () {
this.sourceFhirService = new FhirService(true);
this.targetFhirService = new FhirService(false);
this.quasis = [];
this.riskyQuasis = [];
}

setFhirURL (url: string, isSource: boolean) {
if (isSource) {
this.sourceFhirService.setUrl(url);
} else {
this.targetFhirService.setUrl(url);
}
setFhirService (fhirService: FhirService) {
Vue.prototype.$sourceFhirService = fhirService;
Vue.prototype.$targetFhirService = fhirService;
}

generateEquivalenceClasses (type, parameterMappings, typeMappings) {
Expand Down Expand Up @@ -54,7 +48,7 @@ export class EvaluationService {
return new Promise((resolve, reject) => {
const bulk = JSON.parse(JSON.stringify(entries)).map(element => element.resource);
while (bulk.length) {
promises.push(this.sourceFhirService.validate(bulk.splice(0, 1000)));
promises.push(Vue.prototype.$sourceFhirService.validate(bulk.splice(0, 1000)));
}
Promise.all(promises).then(res => {
resolve(res);
Expand All @@ -75,7 +69,7 @@ export class EvaluationService {
this.savedResourceNumber = 0;
const promises: Array<Promise<any>> = [];
const request = isSource ? 'PUT' : 'POST';
const service = isSource ? this.sourceFhirService : this.targetFhirService;
const service = isSource ? Vue.prototype.$sourceFhirService : Vue.prototype.$targetFhirService;
return new Promise((resolve, reject) => {
const bulk = JSON.parse(JSON.stringify(entries)).map(element => element.resource);
this.savedResourceNumber += bulk.length;
Expand Down
1 change: 0 additions & 1 deletion src/common/services/fhir.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ export class FhirService {
}
}
this.config = isSource ? environment.server.config.source : environment.server.config.target;
this.client = new FhirClient(this.config)
}

/**
Expand Down
126 changes: 126 additions & 0 deletions src/common/services/idb.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@

export class IDBService {

private readonly DB_NAME: string = 'f4hResourceDB'
private readonly DB_VERSION: number = 1
private db: IDBDatabase

constructor () {
this.initDB()
.then(db => this.db = db)
}

/**
* Opens and returns the database
*/
initDB (): Promise<IDBDatabase> {
return new Promise((resolve, reject) => {
const request: IDBOpenDBRequest = indexedDB.open(this.DB_NAME, this.DB_VERSION)

request.onerror = () => reject('Error opening db')
request.onsuccess = e => {
const db: IDBDatabase = (e.target as IDBOpenDBRequest).result
resolve(db)
}

request.onupgradeneeded = e => {
const db: IDBDatabase = (e.target as IDBOpenDBRequest).result
db.createObjectStore('resources', { autoIncrement: true, keyPath: 'resource' })
}
})
}

/**
* Deletes the record with given key (resourceType)
* @param resourceType
*/
delete (resourceType: string): Promise<any> {
return new Promise((resolve, reject) => {
const transaction: IDBTransaction = this.db.transaction(['resources'], 'readwrite')

transaction.onerror = () => reject('Error deleting resource')
transaction.oncomplete = () => resolve()

const store: IDBObjectStore = transaction.objectStore('resources')
store.delete(resourceType)

})
}

/**
* Clears the db - object store
*/
clearAll (): Promise<any> {
return new Promise((resolve, reject) => {
const transaction: IDBTransaction = this.db.transaction(['resources'], 'readwrite')

transaction.onerror = () => reject('Error clearing objectStore')
transaction.oncomplete = () => resolve()

const store: IDBObjectStore = transaction.objectStore('resources')
store.clear()

})
}

/**
* Returns resource value by resource type
* @param resourceType
*/
get (resourceType: string): Promise<any> {
return new Promise((resolve, reject) => {
const transaction: IDBTransaction = this.db.transaction(['resources'], 'readonly')

transaction.onerror = () => reject(`Error getting ${resourceType} resources`)
transaction.oncomplete = () => resolve(result)

const store: IDBObjectStore = transaction.objectStore('resources')
let result: any

const request: IDBRequest = store.get(resourceType)

request.onerror = () => reject(`Error getting ${resourceType} resources`)
request.onsuccess = () => result = request.result

})
}

/**
* Returns all resources in the db
*/
getAll (): Promise<any> {
return new Promise((resolve, reject) => {
const transaction: IDBTransaction = this.db.transaction(['resources'], 'readonly')

transaction.onerror = () => reject('Error getting resources')
transaction.oncomplete = () => resolve(resources)

const store: IDBObjectStore = transaction.objectStore('resources')
let resources: any[] = []

const request: IDBRequest = store.getAll()

request.onerror = () => reject('Error getting resources')
request.onsuccess = () => resources = request.result || []

})
}

/**
* Puts resource data into the db
* @param resource
*/
save (resource: any): Promise<any> {
return new Promise((resolve, reject) => {
const transaction: IDBTransaction = this.db.transaction(['resources'], 'readwrite')

transaction.onerror = () => reject('Error saving resource')
transaction.oncomplete = () => resolve()

const store = transaction.objectStore('resources')
store.put(resource)

})
}

}
11 changes: 5 additions & 6 deletions src/common/utils/fhir-util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ export class FHIRUtils {
});
}

static parseElementDefinitions (node, state): Promise<any> {
static parseElementDefinitions (fhirService: FhirService, node, state): Promise<any> {
return new Promise((resolve, reject) => {
const fhirBase = localStorage.getItem(localStorageKey.FHIR_SOURCE_URL);
const cached = JSON.parse(localStorage.getItem(fhirBase + localStorageKey.STRUCTURE_DEFINITION + node.type) || '{}');
Expand All @@ -50,7 +50,6 @@ export class FHIRUtils {
} else {
if (node.type === 'Reference') resolve(node);
if (fhirBase) {
const fhirService: FhirService = new FhirService(true, fhirBase);
fhirService.search('StructureDefinition', {url: environment.extendibleDataTypes[node.type]}, true)
.then(res => {
if (res.data.total) {
Expand All @@ -67,22 +66,22 @@ export class FHIRUtils {
})
}

static filterDataTypes (tree: fhir.ElementTree[], state): fhir.ElementTree[] {
static filterDataTypes (fhirService: FhirService, tree: fhir.ElementTree[], state): fhir.ElementTree[] {
tree.map(node => {
if (!node.type) { // DomainResource
node.children = node.children?.filter(child => child.label && !environment.attributesToBeFiltered.DomainResource.includes(child.label));
} else if (environment.attributesToBeFiltered[node.type]) {
node.children = node.children?.filter(child => node.type && child.label && !environment.attributesToBeFiltered[node.type].includes(child.label));
} else if (environment.extendibleDataTypes[node.type] && (!node.children || !node.children.length)) {
this.parseElementDefinitions(node, state).then(res => {
this.parseElementDefinitions(fhirService, node, state).then(res => {
node = res;
if (node.children && node.children.length) {
node.children = this.filterDataTypes(JSON.parse(JSON.stringify(node.children)), state);
node.children = this.filterDataTypes(fhirService, JSON.parse(JSON.stringify(node.children)), state);
}
}).catch(err => err);
}
if (node.children && node.children.length) {
node.children = this.filterDataTypes(JSON.parse(JSON.stringify(node.children)), state);
node.children = this.filterDataTypes(fhirService, JSON.parse(JSON.stringify(node.children)), state);
}
});
return tree;
Expand Down
20 changes: 20 additions & 0 deletions src/common/utils/ipc-channel-util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,24 @@ export class IpcChannelUtil {
public static SELECTED_CONFIGURATION = 'selected-configuration'
}

public static Fhir = class {
public static SET_SOURCE_FHIR_BASE = 'set-source-fhir-base'
public static SET_TARGET_FHIR_BASE = 'set-target-fhir-base'
}

public static Deidentifier = class {
public static SET_DEIDENTIFICATION_SERVICE = 'set-deidentification-service'
public static SET_EVALUATION_SERVICE = 'set-evaluation-service'
public static FETCH_ALL_DATA = 'fetch-all-data'
public static DEIDENTIFY = 'de-identify'
public static VALIDATE_ENTRIES = 'validate-entries'
public static SAVE_TO_REPO = 'save-to-repo'
public static FETCH_ALL_DATA_RES_X = (resourceType: string) => `fetch-all-data-res-${resourceType}`
public static DEIDENTIFY_RES_X = (resourceType: string) => `de-identify-res-${resourceType}`
public static DEIDENTIFY_RISKS_RES_X = (resourceType: string) => `de-identify-risks-res-${resourceType}`
public static VALIDATE_ENTRIES_RES_X = (resourceType: string) => `validate-entries-res-${resourceType}`
public static SAVE_TO_REPO_RES_X = (resourceType: string) => `save-to-repo-res-${resourceType}`

}

}
4 changes: 3 additions & 1 deletion src/common/utils/local-storage-util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,7 @@ export class LocalStorageUtil {
public static FHIR_SOURCE_URL = 'fhirSourceUrl'
public static FHIR_TARGET_URL = 'fhirTargetUrl'
public static STRUCTURE_DEFINITION = '-StructureDefinition-'

public static SHOW_BANNER_CONF_MANAGER = 'showBannerConfigurationManager'
public static SHOW_BANNER_DEIDENTIFIER = 'showBannerDeidentifier'
public static SHOW_BANNER_FHIR_ATTRIBUTE = 'showBannerFhirAttribute'
}
17 changes: 17 additions & 0 deletions src/common/utils/vuex-store-util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,4 +96,21 @@ export class VuexStoreUtil {

}

public static IDB = class {

// Getters
// ..

// Mutations
// ..

// Actions
public static DELETE = 'idbDelete'
public static CLEAR_ALL = 'idbClearAll'
public static GET = 'idbGet'
public static GET_ALL = 'idbGetAll'
public static SAVE = 'idbSave'

}

}
Loading

0 comments on commit 97099a2

Please sign in to comment.