diff --git a/src/views/portfolio/projects/ProjectComponents.vue b/src/views/portfolio/projects/ProjectComponents.vue index ecee9cfab..5780bc833 100644 --- a/src/views/portfolio/projects/ProjectComponents.vue +++ b/src/views/portfolio/projects/ProjectComponents.vue @@ -35,10 +35,14 @@ }} {{ @@ -52,10 +56,14 @@ {{ @@ -151,6 +159,8 @@ export default { }, data() { return { + isDownloadingBom: false, + isDownloadingTable: false, labelIcon: { dataOn: '\u2713', dataOff: '\u2715', @@ -410,6 +420,10 @@ export default { this.$refs.table.uncheckAll(); }, downloadBom: function (data) { + if (this.isDownloadingBom) { + return; + } + this.isDownloadingBom = true; let url = `${this.$api.BASE_URL}/${this.$api.URL_BOM}/cyclonedx/project/${this.uuid}`; this.axios .request({ @@ -438,6 +452,9 @@ export default { link.setAttribute('download', filename); document.body.appendChild(link); link.click(); + }) + .finally(() => { + this.isDownloadingBom = false; }); }, buildTableFile: function (json, fileType) { @@ -469,8 +486,16 @@ export default { } }, downloadTable: async function (fileType) { - const result = await this.downloadTableJson(); - this.buildTableFile(result, fileType); + if (this.isDownloadingTable) { + return; + } + this.isDownloadingTable = true; + try { + const result = await this.downloadTableJson(); + this.buildTableFile(result, fileType); + } finally { + this.isDownloadingTable = false; + } }, downloadTableJson: async function () { let url = `${this.$api.BASE_URL}/${this.$api.URL_COMPONENT}/project/${this.uuid}?limit=1000000&offset=0`; diff --git a/src/views/portfolio/projects/ProjectFindings.vue b/src/views/portfolio/projects/ProjectFindings.vue index 604cb8759..e906ec759 100644 --- a/src/views/portfolio/projects/ProjectFindings.vue +++ b/src/views/portfolio/projects/ProjectFindings.vue @@ -25,13 +25,18 @@ id="export-vex-button" size="md" variant="outline-primary" + :disabled="isExportingVex" @click="downloadVex()" v-permission:or="[ PERMISSIONS.VIEW_VULNERABILITY, PERMISSIONS.VULNERABILITY_ANALYSIS, ]" > - {{ $t('message.export_vex') }} + + {{ $t('message.export_vex') }} {{ $t('message.export_vex_tooltip') @@ -41,13 +46,18 @@ id="export-vdr-button" size="md" variant="outline-primary" + :disabled="isExportingVdr" @click="downloadVdr()" v-permission:or="[ PERMISSIONS.VIEW_VULNERABILITY, PERMISSIONS.VULNERABILITY_ANALYSIS, ]" > - {{ $t('message.export_vdr') }} + + {{ $t('message.export_vdr') }} {{ $t('message.export_vdr_tooltip') @@ -149,6 +159,8 @@ export default { data() { return { showSuppressedFindings: this.showSuppressedFindings, + isExportingVex: false, + isExportingVdr: false, labelIcon: { dataOn: '\u2713', dataOff: '\u2715', @@ -438,6 +450,10 @@ export default { return url; }, downloadVex: function () { + if (this.isExportingVex) { + return; + } + this.isExportingVex = true; let url = `${this.$api.BASE_URL}/${this.$api.URL_VEX}/cyclonedx/project/${this.uuid}`; this.axios .request({ @@ -464,9 +480,16 @@ export default { link.setAttribute('download', filename); document.body.appendChild(link); link.click(); + }) + .finally(() => { + this.isExportingVex = false; }); }, downloadVdr: function () { + if (this.isExportingVdr) { + return; + } + this.isExportingVdr = true; let url = `${this.$api.BASE_URL}/${this.$api.URL_BOM}/cyclonedx/project/${this.uuid}`; this.axios .request({ @@ -495,6 +518,9 @@ export default { link.setAttribute('download', filename); document.body.appendChild(link); link.click(); + }) + .finally(() => { + this.isExportingVdr = false; }); }, reAnalyze: function (data) {