Skip to content
This repository has been archived by the owner on Jul 9, 2024. It is now read-only.

Commit

Permalink
feat(export): download clinical & biospec
Browse files Browse the repository at this point in the history
Closes #1466
  • Loading branch information
Terry Lin authored and Terry Lin committed Mar 18, 2016
1 parent 286fc9f commit f3c382b
Show file tree
Hide file tree
Showing 11 changed files with 195 additions and 7 deletions.
1 change: 1 addition & 0 deletions app/scripts/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,7 @@ angular
"ngApp.annotations",
"ngApp.home",
"ngApp.projects",
"ngApp.cases",
"ngApp.components",
"ngApp.cart",
"ngApp.notFound",
Expand Down
24 changes: 22 additions & 2 deletions app/scripts/cart/cart.controllers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,19 @@ module ngApp.cart.controllers {
pluralDefaultText: "authorization levels"
};

this.clinicalDataExportFilters = this.biospecimenDataExportFilters = {
'files.file_id': this.CartService.getFileIds()
};
// TODO: Change `clinical` to those clinical objects (5 of them) once the data model change occurs.
this.clinicalDataExportExpands = ['clinical'];
this.clinicalDataExportFileName = 'clinical.cart';

this.biospecimenDataExportExpands =
['samples','samples.portions','samples.portions.analytes','samples.portions.analytes.aliquots',
'samples.portions.analytes.aliquots.annotations','samples.portions.analytes.annotations',
'samples.portions.submitter_id','samples.portions.slides','samples.portions.annotations',
'samples.portions.center'];
this.biospecimenDataExportFileName = 'biospecimen.cart';
}

getSummary() {
Expand Down Expand Up @@ -127,7 +140,14 @@ module ngApp.cart.controllers {
}

refresh(): void {
var filters = {'content': [{'content': {'field': 'files.file_id', 'value': this.CartService.getFileIds()}, 'op': 'in'}], 'op': 'and'};
const fileIds = this.CartService.getFileIds();
// in the event that our cart is empty
if (fileIds.length < 1) {
this.files = {};
return;
}

var filters = {'content': [{'content': {'field': 'files.file_id', 'value': fileIds}, 'op': 'in'}], 'op': 'and'};
var fileOptions = {
filters: filters,
fields: ['access', 'file_name', 'file_id', 'data_type', 'data_format', 'file_size', 'annotations.annotation_id'],
Expand All @@ -141,7 +161,7 @@ module ngApp.cart.controllers {
this.getSummary();
}
});
this.ParticipantsService.getParticipants({filters: filters}, 'POST').then((data: IParticipants) => {
this.ParticipantsService.getParticipants({filters: filters, size: 0}, 'POST').then((data: IParticipants) => {
this.participantCount = data.pagination.total;
});
}
Expand Down
27 changes: 26 additions & 1 deletion app/scripts/cart/templates/cart.html
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ <h4 class="panel-title" data-translate>Notes</h4>
<section class="row items-pane" data-ng-if="cc.files.hits.length">
<div class="col-md-12 col-lg-12 col-sm-12">
<div class="pull-right">
<split-control data-control-label-text="Download Metadata" data-no-split="true" data-icon-classes="fa fa-download">
<split-control data-control-label-text="Download" data-no-split="true" data-icon-classes="fa fa-download">
<split-control-option data-option-label-text="Download Manifest File">
<a data-download-manifest-cart data-downloader id="manifest-button" href="javascript:void(0)">
<i class="fa" ng-class="{'fa-file-code-o': !active, 'fa-spinner fa-pulse': active}"></i>
Expand All @@ -73,7 +73,32 @@ <h4 class="panel-title" data-translate>Notes</h4>
<i class="fa" ng-class="{'fa-download': !active, 'fa-spinner fa-pulse': active}"></i> <span data-translate>Download Cart (Web Browser)</span>
</a>
</split-control-option>

<split-control-option data-option-label-text="Download Clinical">
<export-cases-button
data-filter-key-values=cc.clinicalDataExportFilters
data-expands=cc.clinicalDataExportExpands
data-filename=cc.clinicalDataExportFileName
data-size=cc.participantCount
data-text-normal="Download Clinical"
data-text-in-progress="Processing"
data-style-class="fa">
</export-cases-button>
</split-control-option>

<split-control-option data-option-label-text="Download Biospecimen">
<export-cases-button
data-filter-key-values=cc.biospecimenDataExportFilters
data-expands=cc.biospecimenDataExportExpands
data-filename=cc.biospecimenDataExportFileName
data-size=cc.participantCount
data-text-normal="Download Biospecimen"
data-text-in-progress="Processing"
data-style-class="fa">
</export-cases-button>
</split-control-option>
</split-control>

<a type="button"
class="btn btn-danger"
id="clear-button"
Expand Down
64 changes: 64 additions & 0 deletions app/scripts/cases/cases.directives.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
module ngApp.cases.directives {
const ExportCasesButton = (config: IGDCConfig): ng.IDirective => ({
restrict: 'E',
replace: true,
scope: {
filterKeyValues: '=',
fields: '=',
expands: '=',
size: '=',
filename: '=',
fileType: '@',
textNormal: '@',
textInProgress: '@',
styleClass: '@',
icon: '@'
},
template: '<a ng-class="[styleClass || \'btn btn-primary\']" data-downloader> \
<i class="fa {{icon || \'fa-download\'}}" ng-class="{\'fa-spinner\': active, \'fa-pulse\': active}" /> \
<span ng-if="textNormal"><span ng-if="! active">&nbsp;{{ ::textNormal }}</span> \
<span ng-if="active">&nbsp;{{ ::textInProgress }}</span></span></a>',
link: ($scope, $element, $attrs) => {
const scope = $scope;
const inProgress = () => {
scope.active = true;
$attrs.$set('disabled', 'disabled');
};
const done = () => {
scope.active = false;
$element.removeAttr('disabled');
};
const url = config.api + '/cases';
const filters = {
op: 'and',
content: _.values(_.mapValues(scope.filterKeyValues, (value, key) => ({
op: 'in',
content: {
field: key,
value: [].concat(value)
}
})))
};

const params = _.merge({
attachment: true,
filters: filters,
fields: ['case_id'].concat(scope.fields || []).join(),
expand: [].concat(scope.expands || []).join(),
format: scope.fileType || 'JSON',
pretty: true,
size: scope.size || 10000
}, scope.filename ? {filename: scope.filename} : {});

$element.on('click', () => {
const checkProgress = scope.download(params, url, () => $element, 'POST');

checkProgress(inProgress, done);
});
scope.active = false;
}
});

angular.module('cases.directives', [])
.directive('exportCasesButton', ExportCasesButton);
}
5 changes: 5 additions & 0 deletions app/scripts/cases/module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module ngApp.cases {
angular.module('ngApp.cases', [
'cases.directives'
]);
}
14 changes: 13 additions & 1 deletion app/scripts/components/ui/biospecimen/biospecimen.controllers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,20 @@ module ngApp.components.ui.biospecimen.controllers {
this.activeBioSpecimenDocType = "sample";

this.bioSpecimenFile = _.find($scope.participant.files, (file) => {
return file.data_subtype.toLowerCase() === "biospecimen data";
return (file.data_subtype || '').toLowerCase() === "biospecimen data";
});

const participant = $scope.participant;
this.hasBiospecimen = !participant.samples;
this.biospecimenDataExportFilters = {
'cases.case_id': participant.case_id
};
this.biospecimenDataExportExpands =
['samples','samples.portions','samples.portions.analytes','samples.portions.analytes.aliquots',
'samples.portions.analytes.aliquots.annotations','samples.portions.analytes.annotations',
'samples.portions.submitter_id','samples.portions.slides','samples.portions.annotations',
'samples.portions.center'];
this.biospecimenDataExportFileName = 'biospecimen.case-' + participant.case_id;
}

displayBioSpecimenDocument(event: any, doc: any, type: string): void {
Expand Down
12 changes: 11 additions & 1 deletion app/scripts/components/ui/biospecimen/templates/biospecimen.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,17 @@
<div class="panel panel-default">
<div class="panel-heading clearfix">
<h3 class="panel-title pull-left" data-translate>Biospecimen</h3>
<data-download-button ng-if="bc.bioSpecimenFile" data-files=bc.bioSpecimenFile data-copy="Download Biospecimen XML" data-dlcopy="Downloading" data-classes="btn pull-right" />

<export-cases-button
ng-disabled="bc.hasBiospecimen"
data-filter-key-values=bc.biospecimenDataExportFilters
data-expands=bc.biospecimenDataExportExpands
data-filename=bc.biospecimenDataExportFileName
data-size=1
data-text-normal="Download JSON"
data-text-in-progress="Processing"
data-style-class="btn pull-right">
</export-cases-button>
</div>
<div class="panel-body">
<div class="col-lg-5 col-md-5">
Expand Down
8 changes: 8 additions & 0 deletions app/scripts/participant/participants.controllers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,14 @@ module ngApp.participants.controllers {
return result;
}, []);

this.hasClinical = !participant.clinical;
this.clinicalDataExportFilters = {
'cases.case_id': participant.case_id
};
// TODO: Change `clinical` to those clinical objects (5 of them) once the data model change occurs.
this.clinicalDataExportExpands = ['clinical'];
this.clinicalDataExportFileName = 'clinical.case-' + participant.case_id;

this.dataCategories = _.reduce(DataCategoryNames.slice(), function(result, name) {
var type = _.find(participant.summary.data_categories, (item) => {
return item.data_category.toLowerCase() === name.toLowerCase();
Expand Down
12 changes: 11 additions & 1 deletion app/scripts/participant/templates/participant.html
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,17 @@ <h3 class="panel-title" data-translate>Summary</h3>
<h3 class="panel-title pull-left" data-translate>
Clinical
</h3>
<data-download-button ng-if="pc.clinicalFile" data-files=pc.clinicalFile data-copy="Download Clinical XML" data-dlcopy="Downloading" data-classes="btn pull-right" />

<export-cases-button
ng-disabled="pc.hasClinical"
data-filter-key-values=pc.clinicalDataExportFilters
data-expands=pc.clinicalDataExportExpands
data-filename=pc.clinicalDataExportFileName
data-size=1
data-text-normal="Download JSON"
data-text-in-progress="Processing"
data-style-class="btn pull-right">
</export-cases-button>
</div>

<table id="clinical-table"
Expand Down
17 changes: 16 additions & 1 deletion app/scripts/projects/projects.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ module ngApp.projects.controllers {
op: "in",
content: {
field: x.content.field.indexOf("summary") === 0 ? "files." + x.content.field.split(".")[2] : "cases.project." + x.content.field,
value: x.content.value
value: x.content.value
}
}))
}
Expand Down Expand Up @@ -243,6 +243,21 @@ module ngApp.projects.controllers {
}
};

const projectId = project.project_id;
this.clinicalDataExportFilters = this.biospecimenDataExportFilters = {
'project.project_id': projectId
};
// TODO: Change `clinical` to those clinical objects (5 of them) once the data model change occurs.
this.clinicalDataExportExpands = ['clinical'];
this.clinicalDataExportFileName = 'clinical.project-' + projectId;

this.biospecimenDataExportExpands =
['samples','samples.portions','samples.portions.analytes','samples.portions.analytes.aliquots',
'samples.portions.analytes.aliquots.annotations','samples.portions.analytes.annotations',
'samples.portions.submitter_id','samples.portions.slides','samples.portions.annotations',
'samples.portions.center'];
this.biospecimenDataExportFileName = 'biospecimen.project-' + projectId;

AnnotationsService.getAnnotations({
filters: {
content: [
Expand Down
18 changes: 18 additions & 0 deletions app/scripts/projects/templates/project.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,24 @@
<h1 class="col-lg-12">
<i class="fa fa-custom fa-annotations"></i>
{{ ::prc.project.project_id }}

<export-cases-button
data-filter-key-values=prc.biospecimenDataExportFilters
data-expands=prc.biospecimenDataExportExpands
data-filename=prc.biospecimenDataExportFileName
data-text-normal="Download Biospecimen JSON"
data-text-in-progress="Processing"
data-style-class="btn pull-right">
</export-cases-button>

<export-cases-button
data-filter-key-values=prc.clinicalDataExportFilters
data-expands=prc.clinicalDataExportExpands
data-filename=prc.clinicalDataExportFileName
data-text-normal="Download Clinical JSON"
data-text-in-progress="Processing"
data-style-class="btn pull-right">
</export-cases-button>
</h1>

<div class="col-lg-12">
Expand Down

0 comments on commit f3c382b

Please sign in to comment.