Files
filebrozer/frontend/src/components/prompts/Copy.vue
Henrique Dias 83492a4dfb feat(frontend): migrate Vue to Composition API
Signed-off-by: Henrique Dias <mail@hacdias.com>
2025-11-13 14:23:20 +01:00

150 lines
3.8 KiB
Vue

<template>
<div class="card floating">
<div class="card-title">
<h2>{{ $t("prompts.copy") }}</h2>
</div>
<div class="card-content">
<p>{{ $t("prompts.copyMessage") }}</p>
<file-list
ref="fileList"
@update:selected="(val: string) => (dest = val)"
tabindex="1"
/>
</div>
<div
class="card-action"
style="display: flex; align-items: center; justify-content: space-between"
>
<template v-if="user?.perm.create">
<button
class="button button--flat"
@click="fileList?.createDir()"
:aria-label="$t('sidebar.newFolder')"
:title="$t('sidebar.newFolder')"
style="justify-self: left"
>
<span>{{ $t("sidebar.newFolder") }}</span>
</button>
</template>
<div>
<button
class="button button--flat button--grey"
@click="closeHovers"
:aria-label="$t('buttons.cancel')"
:title="$t('buttons.cancel')"
tabindex="3"
>
{{ $t("buttons.cancel") }}
</button>
<button
id="focus-prompt"
class="button button--flat"
@click="copy"
:aria-label="$t('buttons.copy')"
:title="$t('buttons.copy')"
tabindex="2"
>
{{ $t("buttons.copy") }}
</button>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { ref, inject } from "vue";
import { storeToRefs } from "pinia";
import { useRoute, useRouter } from "vue-router";
import { useFileStore } from "@/stores/file";
import { useLayoutStore } from "@/stores/layout";
import { useAuthStore } from "@/stores/auth";
import FileList from "./FileList.vue";
import { files as api } from "@/api";
import buttons from "@/utils/buttons";
import * as upload from "@/utils/upload";
import { removePrefix } from "@/api/utils";
const route = useRoute();
const router = useRouter();
const $showError = inject<(error: unknown) => void>("$showError");
const fileStore = useFileStore();
const layoutStore = useLayoutStore();
const authStore = useAuthStore();
const { req, selected } = storeToRefs(fileStore);
const { user } = storeToRefs(authStore);
const { showHover, closeHovers } = layoutStore;
const fileList = ref<InstanceType<typeof FileList> | null>(null);
const dest = ref<string | null>(null);
const copy = async (event: Event) => {
event.preventDefault();
const items: Array<{ from: string; to: string; name: string }> = [];
// Create a new promise for each file.
for (const item of selected.value) {
items.push({
from: req.value!.items[item].url,
to: dest.value! + encodeURIComponent(req.value!.items[item].name),
name: req.value!.items[item].name,
});
}
const action = async (overwrite: boolean, rename: boolean) => {
buttons.loading("copy");
await api
.copy(items, overwrite, rename)
.then(() => {
buttons.success("copy");
fileStore.preselect = removePrefix(items[0].to);
if (route.path === dest.value) {
fileStore.reload = true;
return;
}
router.push({ path: dest.value! });
})
.catch((e) => {
buttons.done("copy");
$showError?.(e);
});
};
if (route.path === dest.value) {
closeHovers();
action(false, true);
return;
}
const dstItems = (await api.fetch(dest.value!)).items;
const conflict = upload.checkConflict(items as any, dstItems);
let overwrite = false;
let rename = false;
if (conflict) {
showHover({
prompt: "replace-rename",
confirm: (event: Event, option: string) => {
overwrite = option == "overwrite";
rename = option == "rename";
event.preventDefault();
closeHovers();
action(overwrite, rename);
},
});
return;
}
action(overwrite, rename);
};
</script>