diff --git a/README.md b/README.md
index 057829ee..4a7c9d25 100644
--- a/README.md
+++ b/README.md
@@ -15,7 +15,7 @@ It is necessary to install and configure the following dependencies:
After installing Node, you should be able to run the following command to install development tools.
You will only need to run this command when dependencies change in [package.json](package.json).
- npm install
+ yarn install
### Prepare Firebase Realtime Database
1. Go to [Firebase Console] and login with your Google account.
diff --git a/codedoc/CODEDOC.md b/codedoc/CODEDOC.md
new file mode 100644
index 00000000..e21feecf
--- /dev/null
+++ b/codedoc/CODEDOC.md
@@ -0,0 +1,80 @@
+# Code Tutorial
+## Configuration Files
+**environment.ts**: The config file used to connect firebase realtime database, set oncotree version and `dev/prod` configs.
+**firebase.json**: The firebase connection auth file generated by Google API service, used to connect Firebase in backend.
+**heroku-mongo.yml**: The mongo connection setting which should be copied and pasted in `application-prod.yml/application-dev.yml`.
+**token**: The trial curation API authentication token.
+
+## File Types
+In the trial curation platform, the frontend code root directory is `/matchminer-curate/src/main/webapp/app`.
+Each folder is a component or service folder. Services only have `*.service.ts` files which can be thought as
+utility classes and used in components.
+
+Most components have 4 files:
+```
+ *.component.html: includes all html related code.
+ *.component.ts: contains functions used in *.component.html.
+ *.model.ts: defines data structure of objects used in *.component.ts.
+ *.scss: writes all css classes used in *.component.html.
+```
+
+## Components
+
+### Meta(jhi-meta)
+Display trial metadata for all trials in a table. A trial meta record will be generated automatically when every time
+users import a new trial from cancer.gov, which is implemented in `importTrialsFromNct()`.
+```
+this.metaService.setMetaRecord(metaRecord);
+```
+
+### Trial(jhi-trial)
+The main page includes all functions related to trial operations and contains multiple components listed below.
+The trial curation is a real time procedure that means users operations on a trial will be broadcast to all sub components,
+which is implemented by creating multiple observable objects(watchers) and monitoring them.
+All observable objects are created in Trial Service and monitored in constructor methods of referenced components.
+
+### Arm(jhi-arm)
+The arm section stores arm meta info and includes the drug component.
+
+### Drug(jhi-drug)
+The component can be used to store a single drug treatment and combination therapy(drug A + drug B).
+
+### Panel(jhi-panel)
+It contains all node related operations, including add, delete, edit, move, clone and switch.
+There is a very important class object called **MovingPath** which contains `from` and `to`.
+When a user moves a node, we need to store the source path in `from` and destination path in `to` first,
+and then clone, copy and paste the node.
+
+### Match(jhi-match)
+The Match component is a big set of clinical and genomic nodes. They are connected by `AND/OR` logistic symbols.
+
+### Clinical(jhi-clinical)
+The Clinical node contains patient data like `age_numerical`, `oncotree_primary_diagnosis` and `gender`.
+Either `age_numerical` and `oncotree_primary_diagnosis` is **required**.
+
+### Genomic(jhi-genomic)
+
+The genomic node contains gene data like `hugo_symbol`, `annotated_variant`, `germline` and `matching_examples`.
+Both `hugo_symbol` and `annotated_variant` are **required**.
+
+## Services
+### Connection
+All API http requests should be put here.
+
+### Trial
+Trial service provides all utility functions related to trials.
+All observable objects and update services related to trial should be put here.
+
+### Email
+Email service is a simple service that only has the sending emails function.
+
+### Meta
+All Meta page related utility functions should be put here.
+
+
+## Relationship between components
+### Trials Page
+
+
+### Meta Page
+
diff --git a/codedoc/meta.png b/codedoc/meta.png
new file mode 100644
index 00000000..7fa7b452
Binary files /dev/null and b/codedoc/meta.png differ
diff --git a/codedoc/trials.png b/codedoc/trials.png
new file mode 100644
index 00000000..b30f6f9e
Binary files /dev/null and b/codedoc/trials.png differ
diff --git a/package-lock.json b/package-lock.json
index 0d6ccaac..d81adc8e 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1223,6 +1223,63 @@
"typescript": "~2.6.2"
}
},
+ "@sentry/browser": {
+ "version": "4.6.6",
+ "resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-4.6.6.tgz",
+ "integrity": "sha512-+9VsQ+oQYU+PYlLJG2ex7JCMSVQbnUvWPI2uZOofWdI9sWIPUub3boWItMzRQNQ1T4S3FZd4FqAWNFd3azdnBw==",
+ "requires": {
+ "@sentry/core": "4.6.6",
+ "@sentry/types": "4.5.3",
+ "@sentry/utils": "4.6.5",
+ "tslib": "^1.9.3"
+ }
+ },
+ "@sentry/core": {
+ "version": "4.6.6",
+ "resolved": "https://registry.npmjs.org/@sentry/core/-/core-4.6.6.tgz",
+ "integrity": "sha512-7z9HKLTNr3zVBR3tBRheTxkkkuK2IqISUc5Iyo3crN2OecOLtpptT96f5XjLndBEL2ab39eCBPpA5OFjbpzrIA==",
+ "requires": {
+ "@sentry/hub": "4.6.5",
+ "@sentry/minimal": "4.6.5",
+ "@sentry/types": "4.5.3",
+ "@sentry/utils": "4.6.5",
+ "tslib": "^1.9.3"
+ }
+ },
+ "@sentry/hub": {
+ "version": "4.6.5",
+ "resolved": "https://registry.npmjs.org/@sentry/hub/-/hub-4.6.5.tgz",
+ "integrity": "sha512-v9vee8s8C1fK/DPtNOzv6r+AMbPDOWfnasouNcBUkbQUSN5wUNyCDvt51QbWaw5kMMY5TSqjdVqY6gXQZI0APQ==",
+ "requires": {
+ "@sentry/types": "4.5.3",
+ "@sentry/utils": "4.6.5",
+ "tslib": "^1.9.3"
+ }
+ },
+ "@sentry/minimal": {
+ "version": "4.6.5",
+ "resolved": "https://registry.npmjs.org/@sentry/minimal/-/minimal-4.6.5.tgz",
+ "integrity": "sha512-tf+J+uUNmSgzC7d9JSN8Ekw1HeBAX87Efa/jyFbzLvaw80oibvTiLSLqDjQ9PgvyIzBUuuPImkS2NpvPQGWFtg==",
+ "requires": {
+ "@sentry/hub": "4.6.5",
+ "@sentry/types": "4.5.3",
+ "tslib": "^1.9.3"
+ }
+ },
+ "@sentry/types": {
+ "version": "4.5.3",
+ "resolved": "https://registry.npmjs.org/@sentry/types/-/types-4.5.3.tgz",
+ "integrity": "sha512-7ll1PAFNjrBNX9rzy3P2qAQrpQwHaDO3uKj735qsnGw34OtAS8Xr8WYrjI14f9fMPa/XIeWvMPb4GMic28V/ag=="
+ },
+ "@sentry/utils": {
+ "version": "4.6.5",
+ "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-4.6.5.tgz",
+ "integrity": "sha512-rTISJtRRbWsd3UE+TkA3QG1C0VzPKPW8w74tieBwYhtTCGmOHNwz2nDC/MZGbGj4OgDmNKKl4CCyQr88EX08hA==",
+ "requires": {
+ "@sentry/types": "4.5.3",
+ "tslib": "^1.9.3"
+ }
+ },
"@swimlane/ngx-datatable": {
"version": "11.3.2",
"resolved": "https://registry.npmjs.org/@swimlane/ngx-datatable/-/ngx-datatable-11.3.2.tgz",
@@ -2152,6 +2209,7 @@
"resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz",
"integrity": "sha1-OciRjO/1eZ+D+UkqhI9iWt0Mdm8=",
"dev": true,
+ "optional": true,
"requires": {
"hoek": "2.x.x"
}
@@ -2492,7 +2550,8 @@
"ansi-regex": {
"version": "2.1.1",
"bundled": true,
- "dev": true
+ "dev": true,
+ "optional": true
},
"aproba": {
"version": "1.2.0",
@@ -2513,12 +2572,14 @@
"balanced-match": {
"version": "1.0.0",
"bundled": true,
- "dev": true
+ "dev": true,
+ "optional": true
},
"brace-expansion": {
"version": "1.1.11",
"bundled": true,
"dev": true,
+ "optional": true,
"requires": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
@@ -2533,17 +2594,20 @@
"code-point-at": {
"version": "1.1.0",
"bundled": true,
- "dev": true
+ "dev": true,
+ "optional": true
},
"concat-map": {
"version": "0.0.1",
"bundled": true,
- "dev": true
+ "dev": true,
+ "optional": true
},
"console-control-strings": {
"version": "1.1.0",
"bundled": true,
- "dev": true
+ "dev": true,
+ "optional": true
},
"core-util-is": {
"version": "1.0.2",
@@ -2660,7 +2724,8 @@
"inherits": {
"version": "2.0.3",
"bundled": true,
- "dev": true
+ "dev": true,
+ "optional": true
},
"ini": {
"version": "1.3.5",
@@ -2672,6 +2737,7 @@
"version": "1.0.0",
"bundled": true,
"dev": true,
+ "optional": true,
"requires": {
"number-is-nan": "^1.0.0"
}
@@ -2686,6 +2752,7 @@
"version": "3.0.4",
"bundled": true,
"dev": true,
+ "optional": true,
"requires": {
"brace-expansion": "^1.1.7"
}
@@ -2693,12 +2760,14 @@
"minimist": {
"version": "0.0.8",
"bundled": true,
- "dev": true
+ "dev": true,
+ "optional": true
},
"minipass": {
"version": "2.3.5",
"bundled": true,
"dev": true,
+ "optional": true,
"requires": {
"safe-buffer": "^5.1.2",
"yallist": "^3.0.0"
@@ -2717,6 +2786,7 @@
"version": "0.5.1",
"bundled": true,
"dev": true,
+ "optional": true,
"requires": {
"minimist": "0.0.8"
}
@@ -2797,7 +2867,8 @@
"number-is-nan": {
"version": "1.0.1",
"bundled": true,
- "dev": true
+ "dev": true,
+ "optional": true
},
"object-assign": {
"version": "4.1.1",
@@ -2809,6 +2880,7 @@
"version": "1.4.0",
"bundled": true,
"dev": true,
+ "optional": true,
"requires": {
"wrappy": "1"
}
@@ -2894,7 +2966,8 @@
"safe-buffer": {
"version": "5.1.2",
"bundled": true,
- "dev": true
+ "dev": true,
+ "optional": true
},
"safer-buffer": {
"version": "2.1.2",
@@ -2930,6 +3003,7 @@
"version": "1.0.2",
"bundled": true,
"dev": true,
+ "optional": true,
"requires": {
"code-point-at": "^1.0.0",
"is-fullwidth-code-point": "^1.0.0",
@@ -2949,6 +3023,7 @@
"version": "3.0.1",
"bundled": true,
"dev": true,
+ "optional": true,
"requires": {
"ansi-regex": "^2.0.0"
}
@@ -2992,12 +3067,14 @@
"wrappy": {
"version": "1.0.2",
"bundled": true,
- "dev": true
+ "dev": true,
+ "optional": true
},
"yallist": {
"version": "3.0.3",
"bundled": true,
- "dev": true
+ "dev": true,
+ "optional": true
}
}
},
@@ -6710,7 +6787,8 @@
},
"ansi-regex": {
"version": "2.1.1",
- "bundled": true
+ "bundled": true,
+ "optional": true
},
"aproba": {
"version": "1.2.0",
@@ -6728,11 +6806,13 @@
},
"balanced-match": {
"version": "1.0.0",
- "bundled": true
+ "bundled": true,
+ "optional": true
},
"brace-expansion": {
"version": "1.1.11",
"bundled": true,
+ "optional": true,
"requires": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
@@ -6745,15 +6825,18 @@
},
"code-point-at": {
"version": "1.1.0",
- "bundled": true
+ "bundled": true,
+ "optional": true
},
"concat-map": {
"version": "0.0.1",
- "bundled": true
+ "bundled": true,
+ "optional": true
},
"console-control-strings": {
"version": "1.1.0",
- "bundled": true
+ "bundled": true,
+ "optional": true
},
"core-util-is": {
"version": "1.0.2",
@@ -6856,7 +6939,8 @@
},
"inherits": {
"version": "2.0.3",
- "bundled": true
+ "bundled": true,
+ "optional": true
},
"ini": {
"version": "1.3.5",
@@ -6866,6 +6950,7 @@
"is-fullwidth-code-point": {
"version": "1.0.0",
"bundled": true,
+ "optional": true,
"requires": {
"number-is-nan": "^1.0.0"
}
@@ -6878,17 +6963,20 @@
"minimatch": {
"version": "3.0.4",
"bundled": true,
+ "optional": true,
"requires": {
"brace-expansion": "^1.1.7"
}
},
"minimist": {
"version": "0.0.8",
- "bundled": true
+ "bundled": true,
+ "optional": true
},
"minipass": {
"version": "2.3.5",
"bundled": true,
+ "optional": true,
"requires": {
"safe-buffer": "^5.1.2",
"yallist": "^3.0.0"
@@ -6905,6 +6993,7 @@
"mkdirp": {
"version": "0.5.1",
"bundled": true,
+ "optional": true,
"requires": {
"minimist": "0.0.8"
}
@@ -6977,7 +7066,8 @@
},
"number-is-nan": {
"version": "1.0.1",
- "bundled": true
+ "bundled": true,
+ "optional": true
},
"object-assign": {
"version": "4.1.1",
@@ -6987,6 +7077,7 @@
"once": {
"version": "1.4.0",
"bundled": true,
+ "optional": true,
"requires": {
"wrappy": "1"
}
@@ -7062,7 +7153,8 @@
},
"safe-buffer": {
"version": "5.1.2",
- "bundled": true
+ "bundled": true,
+ "optional": true
},
"safer-buffer": {
"version": "2.1.2",
@@ -7092,6 +7184,7 @@
"string-width": {
"version": "1.0.2",
"bundled": true,
+ "optional": true,
"requires": {
"code-point-at": "^1.0.0",
"is-fullwidth-code-point": "^1.0.0",
@@ -7109,6 +7202,7 @@
"strip-ansi": {
"version": "3.0.1",
"bundled": true,
+ "optional": true,
"requires": {
"ansi-regex": "^2.0.0"
}
@@ -7147,11 +7241,13 @@
},
"wrappy": {
"version": "1.0.2",
- "bundled": true
+ "bundled": true,
+ "optional": true
},
"yallist": {
"version": "3.0.3",
- "bundled": true
+ "bundled": true,
+ "optional": true
}
}
},
@@ -8554,7 +8650,8 @@
"version": "2.16.3",
"resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz",
"integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0=",
- "dev": true
+ "dev": true,
+ "optional": true
},
"hosted-git-info": {
"version": "2.5.0",
diff --git a/package.json b/package.json
index d5a41898..fe3c130a 100644
--- a/package.json
+++ b/package.json
@@ -106,7 +106,8 @@
"xml2js": "0.4.17"
},
"engines": {
- "node": ">=6.9.0"
+ "node": "8.9.4",
+ "yarn": "1.3.2"
},
"resolutions": {
"source-map": "0.6.1"
diff --git a/src/main/webapp/app/app.module.ts b/src/main/webapp/app/app.module.ts
index fc618c82..98d4aa63 100644
--- a/src/main/webapp/app/app.module.ts
+++ b/src/main/webapp/app/app.module.ts
@@ -45,7 +45,6 @@ import {
import { EmailService } from './service/email.service';
import { ConverterComponent } from './converter/converter.component';
import { ConnectionService } from './service/connection.service';
-import { MainutilService } from './service/mainutil.service';
import { DrugComponent } from './drug/drug.component';
import { MetaComponent } from './meta/meta.component';
import { MetaService } from './service/meta.service';
@@ -55,7 +54,8 @@ import { NgxDatatableModule } from '@swimlane/ngx-datatable';
import * as Sentry from '@sentry/browser';
Sentry.init({
- dsn: 'https://73c005cfa16b49b9825b0ae57b7b9234@sentry.io/1423208'
+ dsn: environment.sentry_dsn,
+ blacklistUrls: [new RegExp('.*localhost.*')]
});
@Injectable()
@@ -109,7 +109,6 @@ export class SentryErrorHandler implements ErrorHandler {
TrialService,
ConnectionService,
EmailService,
- MainutilService,
MetaService,
UserRouteAccessService,
{
diff --git a/src/main/webapp/app/arm/arm.component.html b/src/main/webapp/app/arm/arm.component.html
index b43e911b..f45de772 100644
--- a/src/main/webapp/app/arm/arm.component.html
+++ b/src/main/webapp/app/arm/arm.component.html
@@ -1,7 +1,7 @@
-arm code:
-
+
@@ -62,7 +64,11 @@
-arm eligibility:
{{unit.arm_eligibility}}
-drugs:
-
{{displayDrugName(unit.drugs)}}
+
+
+ 0">- {{displayDrugName(drugGroup)}}
+
+
diff --git a/src/main/webapp/app/arm/arm.component.ts b/src/main/webapp/app/arm/arm.component.ts
index 462153e4..95a792ce 100644
--- a/src/main/webapp/app/arm/arm.component.ts
+++ b/src/main/webapp/app/arm/arm.component.ts
@@ -2,7 +2,8 @@ import { Component, OnInit, Input } from '@angular/core';
import { TrialService } from '../service/trial.service';
import { Arm } from '../arm/arm.model';
import { Drug } from '../drug/drug.model';
-import { MainutilService } from '../service/mainutil.service';
+import MainUtil from '../service/mainutil';
+
@Component({
selector: 'jhi-arm',
templateUrl: './arm.component.html',
@@ -14,11 +15,9 @@ export class ArmComponent implements OnInit {
@Input() path = '';
operationPool: {};
armInput: Arm;
- oncokb: boolean;
+ oncokb = MainUtil.oncokb;
- constructor(private trialService: TrialService, public mainutilService: MainutilService) {
- this.oncokb = this.trialService.oncokb;
- }
+ constructor(private trialService: TrialService) {}
ngOnInit() {
this.trialService.operationPoolObs.subscribe((message) => {
@@ -29,11 +28,12 @@ export class ArmComponent implements OnInit {
});
}
unCheckRadio(key, event) {
- this.armInput[key] = this.mainutilService.unCheckRadio(this.armInput[key], event.target.value);
+ this.armInput[key] = MainUtil.uncheckRadio(this.armInput[key], event.target.value);
+ }
+ displayDrugName(drugGroup: Drug[]) {
+ return drugGroup.map((drug) => drug.name).join(' + ');
}
- displayDrugName(drugs: Array) {
- if (drugs && drugs.length > 0) {
- return drugs.map( (drug) => drug.name).join(', ');
- }
+ addDrugGroup() {
+ this.armInput.drugs.push([]);
}
}
diff --git a/src/main/webapp/app/arm/arm.model.ts b/src/main/webapp/app/arm/arm.model.ts
index 6b51db7d..1753f686 100644
--- a/src/main/webapp/app/arm/arm.model.ts
+++ b/src/main/webapp/app/arm/arm.model.ts
@@ -1,7 +1,7 @@
import { Drug } from "../drug/drug.model";
export interface Arm {
- arm_code: string, // The 1st word of arm_description.
+ arm_code?: string, // The 1st word of arm_description.
arm_description: string, // Arm full name.
arm_name?: string,
arm_internal_id?: string, // Used for matchminer backend.
@@ -9,7 +9,7 @@ export interface Arm {
arm_type?: string, // Arm type(Control Arm)
arm_eligibility?: string, // Store in Firebase and do not send to MongoDB.
arm_info?: string, // Real arm description. Store in Firebase and do not send to MongoDB.
- drugs?: Array,
- match: Array