Skip to content

Commit

Permalink
Re-enable VCF Download by changing from file-anchor to fileDownloadBl…
Browse files Browse the repository at this point in the history
…ob and fileDownloadAsCSV

part of #410 (2nd comment).
manage-genotype.hbs :
 change button ember-csv@file-anchor .vcfExportText to action .vcfExportTextToFile, because file-anchor is not supported in the version of Ember.js framework which #370 upgraded to.
 add input checkbox @userSettings.compressVCF, with label .vcf.gz.

manage-genotype.js : add @userSettings.compressVCF, vcfExportTextToFile().
file-download.js :
 factor fileDownloadBlob() out of fileDownloadAsCSV(); add type as an optional parameter.
 add text2Gzip().
  • Loading branch information
Don-Isdale committed Feb 3, 2025
1 parent 0de299e commit 352f3b3
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 11 deletions.
12 changes: 10 additions & 2 deletions frontend/app/components/panel/manage-genotype.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -345,12 +345,20 @@

<div class="genotype">
{{#if this.vcfExportText.length}}
<button type="button" class="btn btn-info btn-xs">
{{!-- #component "ember-csv@file-anchor" data=this.vcfExportText fileName=this.vcfExportFileName}} VCF Download{{/component --}}
<button type="button" class="btn btn-info btn-xs"
onclick={{action this.vcfExportTextToFile}} >
VCF Download
</button>
{{/if}}

<input type="checkbox"
style="margin-left: 3em;"
checked={{@userSettings.compressVCF}}
oninput={{action (mut @userSettings.compressVCF) value="target.checked"}} >
<label>.vcf.gz</label>
</div>


{{/tab.pane}}
{{/let}}
{{/let}}
Expand Down
34 changes: 32 additions & 2 deletions frontend/app/components/panel/manage-genotype.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import NamesFilters from '../../utils/data/names-filters';
import { toPromiseProxy, toArrayPromiseProxy, addObjectArrays, arrayClear } from '../../utils/ember-devel';
import { thenOrNow, contentOf, pollCondition, promiseThrottle } from '../../utils/common/promises';
import { responseTextParseHtml } from '../../utils/domElements';
import { fileDownloadBlob, fileDownloadAsCSV, text2Gzip } from '../../utils/dom/file-download';
import { clipboard_writeText } from '../../utils/common/html';
import { arrayChoose } from '../../utils/common/arrays';
import { intervalSize } from '../../utils/interval-calcs';
Expand Down Expand Up @@ -183,6 +184,7 @@ function featureHasSamplesLoaded(feature) {
* .replaceResults default: false
* .showResultText default: false
* .compressVCF default : true
* .showConfigureLookup default: false
* .showSampleFilters default : false
Expand Down Expand Up @@ -475,6 +477,9 @@ export default class PanelManageGenotypeComponent extends Component {
if (userSettings.showResultText === undefined) {
userSettings.showResultText = false;
}
if (userSettings.compressVCF === undefined) {
userSettings.compressVCF = true;
}
if (userSettings.showConfigureLookup === undefined) {
userSettings.showConfigureLookup = true;
}
Expand Down Expand Up @@ -3155,6 +3160,11 @@ export default class PanelManageGenotypeComponent extends Component {
//----------------------------------------------------------------------------


/**
* @return a file base name for VCF Download of displayed data of this.lookupBlock.
* The base name does not include the extension, because either
* '.vcf.txt' or '.vcf.gz' may be used
*/
@computed(
'lookupDatasetId', 'lookupScope', 'vcfGenotypeLookupDomain',
'vcfGenotypeSamplesSelected', 'requestFormat')
Expand All @@ -3168,8 +3178,7 @@ export default class PanelManageGenotypeComponent extends Component {
'_' + scope +
'_' + domainText +
'_' + this.requestFormat +
'_' + samplesLength +
'.vcf' ;
'_' + samplesLength;
return fileName;
}

Expand Down Expand Up @@ -3954,6 +3963,27 @@ export default class PanelManageGenotypeComponent extends Component {
return combinedP;
}

/** Export as a user file download a VCF file constructed from .headerTextP,
* .vcfGenotypeText via combineHeader()
*
* The exported MIME Type used is 'text/csv' because
* 'text/tsv'is would be interpreted as Vcard, refn
* https://github.com/samtools/hts-specs/issues/407
* https://developer.mozilla.org/en-US/docs/Web/HTTP/MIME_types/Common_types
*/
vcfExportTextToFile() {
this.vcfExportTextP.then(combined => {
const data = combined.join('\n');
if (this.args.userSettings.compressVCF) {
const blobP = text2Gzip(data, 'application/gzip');
blobP.then(blob =>
fileDownloadBlob(this.vcfExportFileName + '.vcf.gz', blob, 'application/gzip'));
} else {
fileDownloadAsCSV(this.vcfExportFileName + '.vcf.txt', data, 'text/plain');
}
});
}

combineHeader(headerText, vcfGenotypeText) {
/** remove trailing \n, so that split does not create a trailing empty line. */
headerText = headerText.trim().split('\n');
Expand Down
45 changes: 38 additions & 7 deletions frontend/app/utils/dom/file-download.js
Original file line number Diff line number Diff line change
@@ -1,22 +1,28 @@
//------------------------------------------------------------------------------

/* global Blob */
/* global removeEventListener */
/* global document */
/* global URL */
/* global CompressionStream */
/* global Response */

//------------------------------------------------------------------------------

export {fileDownloadAsCSV}
/** Trigger a download of a CSV / TSV file containing the given CSV / TSV string
export {fileDownloadBlob, fileDownloadAsCSV}
/** Trigger a download of a file containing the given data blob.
*
* Based on a post on discuss.emberjs.com by skaterdav85, May 2018 :
* fileDownloadBlob() and fileDownloadAsCSV() are partly based on a post on discuss.emberjs.com by skaterdav85, May 2018 :
* https://discuss.emberjs.com/t/whats-the-best-strategy-for-letting-users-download-ember-data-returns-as-csvs/14767/2
*
* @param filename string
* @param blob
*/
function fileDownloadAsCSV(filename, contents) {
function fileDownloadBlob(filename, blob) {
const { document, URL, removeEventListener } = window;
const anchor = document.createElement('a');
anchor.download = filename;
const url = anchor.href = URL.createObjectURL(new Blob([contents], {
type: 'text/csv'
}));
const url = anchor.href = URL.createObjectURL(blob);

//----------------------------------------------------------------------------

Expand All @@ -31,6 +37,16 @@ function fileDownloadAsCSV(filename, contents) {
anchor.click();
URL.revokeObjectURL(url);
anchor.remove();

}
/** Trigger a download of a CSV / TSV file containing the given CSV / TSV string
*
* @param filename string
* @param type default is 'text/csv'
*/
function fileDownloadAsCSV(filename, contents, type = 'text/csv') {
const blob = new Blob([contents], { type });
fileDownloadBlob(filename, blob);
}

//------------------------------------------------------------------------------
Expand Down Expand Up @@ -64,3 +80,18 @@ function exportAsCSVFile(fileName, data, keyArray, columnHeaders, quoteIfNeeded)
}

//------------------------------------------------------------------------------

export { text2Gzip }
/** Compress the given string, and return content for a .gz file download
* @return promise yielding a blob, of gzip data
*/
function text2Gzip(contents, type = 'text/csv') {
const
stream = new CompressionStream("gzip"),
blob = new Blob([contents], { type }),
compressedStream = blob.stream().pipeThrough(stream),
promise = new Response(compressedStream).blob();

return promise;

}

0 comments on commit 352f3b3

Please sign in to comment.