mirror of
https://gitlab.com/CIEFWorldwideSdnBhd/exchange-2.0.git
synced 2026-08-23 22:44:03 +00:00
156 lines
5.1 KiB
Vue
156 lines
5.1 KiB
Vue
<template>
|
|
<span>
|
|
<a :class="[customClass, { 'link-disabled': isDownloading }]" @click.prevent="showPasswordModal">
|
|
<slot></slot>
|
|
<span v-if="isDownloading" class="spinner"></span>
|
|
</a>
|
|
|
|
<modal-component styleType="fill-in" type="passwordPrompt" @close="closeModal">
|
|
<div class="row bg-white p-t-45 p-b-45 p-l-45 p-r-45">
|
|
<div class="col">
|
|
<h4 class="m-b-20 text-center">Enter Password</h4>
|
|
<div class="form-group">
|
|
<input type="password" class="form-control" v-model="password" placeholder="Enter password" @keyup.enter="handleDownload">
|
|
</div>
|
|
<div class="text-danger m-b-10" v-if="error">{{ error }}</div>
|
|
<div class="row">
|
|
<div class="col-6">
|
|
<button class="btn btn-default btn-block" @click="closeModal">Cancel</button>
|
|
</div>
|
|
<div class="col-6">
|
|
<button class="btn btn-primary btn-block" @click="handleDownload" :disabled="isDownloading">
|
|
Download
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</modal-component>
|
|
</span>
|
|
</template>
|
|
|
|
<script>
|
|
export default {
|
|
props: {
|
|
url: {
|
|
type: String,
|
|
required: true,
|
|
},
|
|
customClass: {
|
|
type: String,
|
|
default: ''
|
|
}
|
|
},
|
|
data() {
|
|
return {
|
|
isDownloading: false,
|
|
password: '',
|
|
error: '',
|
|
modalVisible: false
|
|
};
|
|
},
|
|
methods: {
|
|
showPasswordModal() {
|
|
this.password = '';
|
|
this.error = '';
|
|
this.$nextTick(() => {
|
|
$('.modalContainer[data-type="passwordPrompt"]').modal('show');
|
|
});
|
|
},
|
|
closeModal() {
|
|
$('.modalContainer[data-type="passwordPrompt"]').modal('hide');
|
|
},
|
|
async handleDownload() {
|
|
if (!this.password) {
|
|
this.error = 'Please enter a password';
|
|
return;
|
|
}
|
|
|
|
this.isDownloading = true;
|
|
this.error = '';
|
|
|
|
try {
|
|
const response = await fetch(this.url + '?password=' + this.password, {
|
|
method: 'GET',
|
|
headers: {
|
|
'Authorization': 'Bearer ' + this.$store.getters.getAccessToken,
|
|
},
|
|
});
|
|
|
|
if (response.status === 403) {
|
|
this.error = 'Invalid password';
|
|
this.isDownloading = false;
|
|
return;
|
|
}
|
|
|
|
if (response.status === 200) {
|
|
// Check if response is JSON
|
|
const contentType = response.headers.get('content-type');
|
|
if (contentType && contentType.includes('application/json')) {
|
|
const data = await response.json();
|
|
if (data.src) {
|
|
// If JSON contains a file URL, trigger download
|
|
window.location.href = data.src;
|
|
this.closeModal();
|
|
return;
|
|
}
|
|
}
|
|
|
|
// Handle direct file download
|
|
const contentDisposition = response.headers.get('Content-Disposition');
|
|
const filename = contentDisposition ? contentDisposition.split('filename=')[1] : 'downloaded_file';
|
|
|
|
const blob = await response.blob();
|
|
const blobUrl = window.URL.createObjectURL(blob);
|
|
const a = document.createElement('a');
|
|
a.href = blobUrl;
|
|
a.download = filename;
|
|
a.style.display = 'none';
|
|
document.body.appendChild(a);
|
|
a.click();
|
|
document.body.removeChild(a);
|
|
window.URL.revokeObjectURL(blobUrl);
|
|
this.closeModal();
|
|
} else {
|
|
this.error = 'Download failed';
|
|
}
|
|
} catch (error) {
|
|
console.error('Network error:', error);
|
|
this.error = 'Network error occurred';
|
|
} finally {
|
|
this.isDownloading = false;
|
|
}
|
|
}
|
|
}
|
|
};
|
|
</script>
|
|
|
|
<style scoped>
|
|
.spinner {
|
|
border: 2px solid rgba(0, 0, 0, 0.1);
|
|
border-left-color: #000;
|
|
border-radius: 50%;
|
|
width: 20px;
|
|
height: 20px;
|
|
animation: spin 1s linear infinite;
|
|
position: absolute;
|
|
top: 50%;
|
|
left: 50%;
|
|
transform: translate(-50%, -50%);
|
|
}
|
|
|
|
@keyframes spin {
|
|
0% {
|
|
transform: translate(-50%, -50%) rotate(0deg);
|
|
}
|
|
100% {
|
|
transform: translate(-50%, -50%) rotate(360deg);
|
|
}
|
|
}
|
|
|
|
.link-disabled {
|
|
pointer-events: none;
|
|
opacity: 0.6;
|
|
border: none;
|
|
}
|
|
</style> |