Newer
Older
import BootstrapModal from "@/components/modals/BootstrapModal.vue";
import { Modal, Toast } from "bootstrap";
import { onMounted, reactive, watch } from "vue";
import type { _Object as S3Object } from "@aws-sdk/client-s3";
import { useBucketStore } from "@/stores/buckets";
import { useS3ObjectStore } from "@/stores/s3objects";
const objectRepository = useS3ObjectStore();
const props = defineProps<{
modalID: string;
srcObject: S3Object;
srcBucket: string;
destKey: string;
destBucket: string;
uploading: boolean;
}>({
destKey: "",
destBucket: "",
uploading: false,
const bucketRepository = useBucketStore();
const randomIDSuffix = Math.random().toString(16).substring(2, 8);
let copyModal: Modal | null = null;
let successToast: Toast | null = null;
let errorToast: Toast | null = null;
function getFileName(key?: string): string {
if (key == undefined) {
return "";
}
const splittedKey = key.split("/");
return splittedKey[splittedKey.length - 1];
}
function copyObject() {
if (props.srcObject.Key == undefined) {
return;
}
objectRepository
.copyObject(
props.srcBucket,
props.srcObject,
formState.destBucket,
formState.destKey,
)
.then(() => {
copyModal?.hide();
successToast?.show();
formState.destBucket = "";
})
.catch((e) => {
console.error(e);
errorToast?.show();
})
.finally(() => {
formState.uploading = false;
});
}
function modalClosed() {
formState.destBucket = "";
}
watch(
() => props.srcObject.Key,
formState.destKey = newKey ?? "";
);
onMounted(() => {
copyModal = new Modal("#" + props.modalID);
successToast = new Toast("#successToast-" + randomIDSuffix);
errorToast = new Toast("#errorToast-" + randomIDSuffix);
});
</script>
<template>
<div class="toast-container position-fixed top-toast end-0 p-3">
<div
role="alert"
aria-live="assertive"
aria-atomic="true"
class="toast text-bg-success align-items-center border-0"
data-bs-autohide="true"
:id="'successToast-' + randomIDSuffix"
>
<div class="d-flex">
<div class="toast-body">Successfully copied file</div>
<button
type="button"
class="btn-close btn-close-white me-2 m-auto"
data-bs-dismiss="toast"
aria-label="Close"
></button>
</div>
</div>
</div>
<div class="toast-container position-fixed top-toast end-0 p-3">
<div
role="alert"
aria-live="assertive"
aria-atomic="true"
class="toast text-bg-danger align-items-center border-0"
data-bs-autohide="true"
:id="'errorToast-' + randomIDSuffix"
>
<div class="d-flex">
<div class="toast-body">
There has been some Error.<br />
Try again later
</div>
<button
type="button"
class="btn-close btn-close-white me-2 m-auto"
data-bs-dismiss="toast"
aria-label="Close"
></button>
</div>
</div>
</div>
<bootstrap-modal
:modalID="modalID"
:static-backdrop="true"
modal-label="Copy Object Modal"
v-on="{ 'hidden.bs.modal': modalClosed }"
>
<template v-slot:header>
<h4>Copy file {{ getFileName(props.srcObject.Key) }}</h4>
</template>
<template v-slot:body>
<div class="container-fluid">
<div class="row">
<form
class="col-7"
:id="'copyObjectForm' + randomIDSuffix"
@submit.prevent="copyObject"
>
<div class="mb-3">
<label
:for="'destinationBucket' + randomIDSuffix"
class="form-label"
>
Destination Bucket *
</label>
<select
class="form-select text-lowercase"
:id="'destinationBucket' + randomIDSuffix"
required
v-model="formState.destBucket"
>
<option disabled selected>Select one...</option>
<option
v-for="bucket in bucketRepository.writableBuckets"
:key="bucket.name"
:value="bucket.name"
>
</option>
</select>
</div>
<div class="mb-3">
<label :for="'objectKey' + randomIDSuffix" class="form-label"
>Destination Filename *</label
>
<input
type="text"
class="form-control"
:id="'objectKey' + randomIDSuffix"
required
v-model="formState.destKey"
/>
</div>
</form>
<div class="col-5">
You can copy objects. You have to create destination buckets prior
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
to copy.<br />
You can specify folder by using '/' at destination object field. For
example, if you want to copy object under the folder named
'folder1', you need to specify destination object like
'folder1/[your object name]'.
</div>
</div>
</div>
</template>
<template v-slot:footer>
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">
Close
</button>
<button
:disabled="formState.uploading"
type="submit"
:form="'copyObjectForm' + randomIDSuffix"
class="btn btn-primary"
>
<span
v-if="formState.uploading"
class="spinner-border spinner-border-sm"
role="status"
aria-hidden="true"
></span>
Copy
</button>
</template>
</bootstrap-modal>
</template>
<style scoped></style>