feat(export): open export folder

This commit is contained in:
zipg authored and GitHub committed 2026-07-15 19:35:18 +08:00
1 parent 1a8c1b19a0
commit b6581d3dc9
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>