feat(export): open export folder
This commit is contained in:
11 files changed
+53
-3
No files matched your search
@@ -1,12 +1,17 @@
|
||||
<script setup lang="ts">
|
||||
import { computed } from "vue";
|
||||
import { computed, ref } from "vue";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter } from "@/components/ui/dialog";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Loader2, CheckCircle2, XCircle, AlertCircle, X } from "@lucide/vue";
|
||||
import { Loader2, CheckCircle2, XCircle, AlertCircle, FolderOpen, X } from "@lucide/vue";
|
||||
import { useToast } from "@/composables/useToast";
|
||||
import { isTauriRuntime } from "@/lib/backend/tauriRuntime";
|
||||
import * as api from "@/lib/backend/api";
|
||||
|
||||
const { t } = useI18n();
|
||||
const { toast } = useToast();
|
||||
const open = defineModel<boolean>("open", { default: false });
|
||||
const isRevealing = ref(false);
|
||||
|
||||
const props = defineProps<{
|
||||
title: string;
|
||||
@@ -16,6 +21,7 @@ const props = defineProps<{
|
||||
totalRows: number | null;
|
||||
status: string;
|
||||
errorMessage: string | null;
|
||||
filePath?: string | null;
|
||||
disableCancel?: boolean;
|
||||
}>();
|
||||
|
||||
@@ -26,6 +32,7 @@ const emit = defineEmits<{
|
||||
|
||||
const isActive = computed(() => props.status === "Running" || props.status === "Writing");
|
||||
const isFinished = computed(() => props.status === "Done" || props.status === "Error" || props.status === "Cancelled");
|
||||
const canRevealFile = computed(() => props.status === "Done" && !!props.filePath && isTauriRuntime());
|
||||
const progressPercent = computed(() => {
|
||||
if (!props.totalRows || props.totalRows <= 0) return 0;
|
||||
return Math.min(100, Math.round((props.rowsExported / props.totalRows) * 100));
|
||||
@@ -39,6 +46,19 @@ const rowsText = computed(() => {
|
||||
}
|
||||
return t("exportProgress.rowsExported", { count: props.rowsExported.toLocaleString() });
|
||||
});
|
||||
|
||||
async function revealExportFile() {
|
||||
if (!props.filePath || isRevealing.value) return;
|
||||
isRevealing.value = true;
|
||||
try {
|
||||
await api.revealPathInFileManager(props.filePath);
|
||||
} catch (error) {
|
||||
const message = error instanceof Error ? error.message : String(error);
|
||||
toast(t("exportProgress.openFolderFailed", { message }), 5000);
|
||||
} finally {
|
||||
isRevealing.value = false;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -108,6 +128,11 @@ const rowsText = computed(() => {
|
||||
</Button>
|
||||
</template>
|
||||
<template v-else-if="isFinished">
|
||||
<Button v-if="canRevealFile" size="sm" :disabled="isRevealing" @click="revealExportFile">
|
||||
<Loader2 v-if="isRevealing" class="mr-1 h-3.5 w-3.5 animate-spin" />
|
||||
<FolderOpen v-else class="mr-1 h-3.5 w-3.5" />
|
||||
{{ t("exportProgress.openFolder") }}
|
||||
</Button>
|
||||
<Button variant="outline" size="sm" @click="emit('update:open', false)">
|
||||
{{ t("exportProgress.close") }}
|
||||
</Button>
|
||||
|
||||
Reference in new issue
Block a user