Skip to content

Commit 349a82c

Browse files
Added download BOM button to UI that supports all three BOM variants.
DependencyTrack/dependency-track#1365
1 parent 187e96f commit 349a82c

File tree

2 files changed

+42
-0
lines changed

2 files changed

+42
-0
lines changed

src/i18n/locales/en.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,11 @@
155155
"remove_component": "Remove Component",
156156
"upload_bom": "Upload BOM",
157157
"upload": "Upload",
158+
"download_bom": "Download BOM",
159+
"download": "Download",
160+
"inventory": "Inventory",
161+
"inventory_with_vulnerabilities": "Inventory with Vulnerabilities",
162+
"vex_long_desc": "Vulnerability Exploitability Exchange (VEX)",
158163
"reset": "Reset",
159164
"bom_uploaded": "BOM uploaded",
160165
"license_text": "License Text",

src/views/portfolio/projects/ProjectComponents.vue

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,14 @@
1717
v-permission:or="[PERMISSIONS.PORTFOLIO_MANAGEMENT, PERMISSIONS.BOM_UPLOAD]">
1818
<span class="fa fa-upload"></span> {{ $t('message.upload_bom') }}
1919
</b-button>
20+
<b-dropdown variant="outline-primary" v-permission="PERMISSIONS.PORTFOLIO_MANAGEMENT">
21+
<template #button-content>
22+
<span class="fa fa-download"></span> {{ $t('message.download_bom') }}
23+
</template>
24+
<b-dropdown-item @click="downloadBom('inventory')" href="#">{{ $t('message.inventory') }}</b-dropdown-item>
25+
<b-dropdown-item @click="downloadBom('withVulnerabilities')" href="#">{{ $t('message.inventory_with_vulnerabilities') }}</b-dropdown-item>
26+
<b-dropdown-item @click="downloadBom('vex')" href="#">{{ $t('message.vex_long_desc') }}</b-dropdown-item>
27+
</b-dropdown>
2028
</div>
2129
</div>
2230
<bootstrap-table
@@ -198,6 +206,35 @@
198206
}
199207
this.$refs.table.uncheckAll();
200208
},
209+
downloadBom: function (data) {
210+
let url = `${this.$api.BASE_URL}/${this.$api.URL_BOM}/cyclonedx/project/${this.uuid}`;
211+
this.axios.request({
212+
responseType: 'blob',
213+
url: url,
214+
method: 'get',
215+
params: {
216+
format: 'json',
217+
variant: data,
218+
download: 'true'
219+
}
220+
}).then((response) => {
221+
const url = window.URL.createObjectURL(new Blob([response.data]));
222+
const link = document.createElement('a');
223+
link.href = url;
224+
let filename = "bom.json";
225+
let disposition = response.headers["content-disposition"]
226+
if (disposition && disposition.indexOf('attachment') !== -1) {
227+
let filenameRegex = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/;
228+
let matches = filenameRegex.exec(disposition);
229+
if (matches != null && matches[1]) {
230+
filename = matches[1].replace(/['"]/g, '');
231+
}
232+
}
233+
link.setAttribute('download', filename);
234+
document.body.appendChild(link);
235+
link.click();
236+
});
237+
},
201238
tableLoaded: function(data) {
202239
if (data && Object.prototype.hasOwnProperty.call(data, "total")) {
203240
this.$emit('total', data.total);

0 commit comments

Comments
 (0)