@burdenoff/microfe-export 2026.625.1 → 2026.626.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/export/components/ExportStatusBadge.js +1 -1
- package/dist/export/components/ExportStatusBadge.js.map +1 -1
- package/dist/export/components/PageLayout.js +7 -18
- package/dist/export/components/PageLayout.js.map +1 -1
- package/dist/export/pages/CreateExportPage.js +95 -90
- package/dist/export/pages/CreateExportPage.js.map +1 -1
- package/dist/export/pages/ExportDashboardPage.js +148 -94
- package/dist/export/pages/ExportDashboardPage.js.map +1 -1
- package/dist/export/pages/ExportDetailPage.js +157 -134
- package/dist/export/pages/ExportDetailPage.js.map +1 -1
- package/dist/export/pages/ExportHistoryPage.js +147 -142
- package/dist/export/pages/ExportHistoryPage.js.map +1 -1
- package/dist/export/pages/ExportTemplatesPage.js +133 -129
- package/dist/export/pages/ExportTemplatesPage.js.map +1 -1
- package/dist/export/pages/TemplateDetailPage.js +103 -97
- package/dist/export/pages/TemplateDetailPage.js.map +1 -1
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ExportDashboardPage.js","names":[],"sources":["../../../src/export/pages/ExportDashboardPage.tsx"],"sourcesContent":["import {\n Plus,\n Download,\n Clock,\n FileBox,\n ArrowRight,\n Activity,\n CheckCircle2,\n} from \"lucide-react\";\nimport { useI18n } from \"@burdenoff/fe-libs/shared/providers/shell/I18nProvider\";\nimport { GlassCard, EmphasisPanel } from \"@burdenoff/fe-libs/ui\";\nimport { useExport } from \"../providers/ExportProvider\";\nimport { useExportJobs } from \"../hooks/useExportQueries\";\nimport { ExportStatusBadge } from \"../components/ExportStatusBadge\";\nimport { ExportProgressBar } from \"../components/ExportProgressBar\";\nimport { PageLayout, PageSection, EmptyState } from \"../components/PageLayout\";\nimport { cn } from \"../utils/cn\";\nimport { tWithFallback } from \"../utils/i18n\";\n\n/**\n * Helper to join paths correctly, avoiding double slashes\n */\nconst joinPath = (base: string, path: string): string => {\n const cleanBase = base.endsWith(\"/\") ? base.slice(0, -1) : base;\n const cleanPath = path.startsWith(\"/\") ? path : `/${path}`;\n return cleanBase + cleanPath;\n};\n\n/**\n * Export Dashboard Page\n * Overview with recent exports, quick actions, and status summary\n */\nexport function ExportDashboardPage() {\n const { basePath = \"/\", navigate } = useExport();\n const { t } = useI18n();\n const tr = (\n key: string,\n fallback: string,\n params?: Record<string, string | number>,\n ) => tWithFallback(t, key, fallback, params);\n const { data: jobs, isLoading } = useExportJobs({});\n\n const recentJobs = jobs.slice(0, 5);\n const activeJobs = jobs.filter(\n (j) => j.status === \"RUNNING\" || j.status === \"QUEUED\",\n );\n const completedJobs = jobs.filter((j) => j.status === \"COMPLETED\");\n\n const metrics = [\n {\n icon: <Download size={18} />,\n label: tr(\"export.dashboard.metrics.total\", \"Total Exports\"),\n value: jobs.length,\n treatment: \"glass\" as const,\n },\n {\n icon: <Activity size={18} />,\n label: tr(\"export.dashboard.metrics.active\", \"Active\"),\n value: activeJobs.length,\n treatment: \"metric\" as const,\n },\n {\n icon: <CheckCircle2 size={18} />,\n label: tr(\"export.dashboard.metrics.completed\", \"Completed\"),\n value: completedJobs.length,\n treatment: \"metric\" as const,\n },\n ];\n\n const handleNavigate = (path: string) => {\n if (!navigate) return;\n navigate(joinPath(basePath, path));\n };\n\n return (\n <PageLayout\n title={tr(\"export.dashboard.title\", \"Export\")}\n subtitle={tr(\n \"export.dashboard.subtitle\",\n \"Export your workspace data in multiple formats\",\n )}\n icon={<Download size={24} />}\n >\n {/* Metric strip */}\n {!isLoading && jobs.length > 0 && (\n <div className=\"grid grid-cols-1 sm:grid-cols-3 gap-4\">\n {metrics.map((m) => (\n <GlassCard\n key={m.label}\n treatment={m.treatment}\n className=\"p-5 border-border-seam\"\n >\n <div className=\"flex items-center gap-2 text-text-secondary mb-2\">\n {m.icon}\n <span className=\"text-xs font-medium\">{m.label}</span>\n </div>\n <p className=\"text-3xl font-bold tabular-nums text-text-primary\">\n {m.value.toLocaleString()}\n </p>\n </GlassCard>\n ))}\n </div>\n )}\n\n {/* Quick Actions */}\n <div\n className=\"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4\"\n data-tour=\"export-dashboard-quick-actions\"\n >\n {[\n {\n icon: <Plus size={20} />,\n label: tr(\"export.dashboard.actions.newExport.label\", \"New Export\"),\n description: tr(\n \"export.dashboard.actions.newExport.description\",\n \"Create a new data export\",\n ),\n path: \"new\",\n color: \"bg-action-primary-bg/10 text-primary\",\n },\n {\n icon: <Clock size={20} />,\n label: tr(\"export.dashboard.actions.history.label\", \"History\"),\n description: tr(\n \"export.dashboard.actions.history.description\",\n \"View past exports\",\n ),\n path: \"history\",\n color: \"bg-status-info-bg-subtle text-status-info-text\",\n },\n {\n icon: <FileBox size={20} />,\n label: tr(\"export.dashboard.actions.templates.label\", \"Templates\"),\n description: tr(\n \"export.dashboard.actions.templates.description\",\n \"Reusable export configs\",\n ),\n path: \"templates\",\n color: \"bg-accent-purple-subtle text-accent-purple\",\n },\n {\n icon: <Activity size={20} />,\n label: tr(\n \"export.dashboard.actions.activeJobs.label\",\n \"Active Jobs\",\n ),\n description: tr(\n \"export.dashboard.actions.activeJobs.description\",\n \"{count} running\",\n { count: activeJobs.length },\n ),\n path: \"history?status=RUNNING\",\n color: \"bg-status-success-bg-subtle text-status-success-text\",\n },\n ].map((action) => (\n <button\n type=\"button\"\n key={action.path + action.label}\n onClick={() => handleNavigate(action.path)}\n className={cn(\n \"group relative overflow-hidden border border-border-seam rounded-xl p-5\",\n \"bg-bg-surface shadow-[var(--shadow-pop)]\",\n \"hover:border-primary/40 transition-colors duration-200\",\n \"text-left focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/40\",\n )}\n >\n <div className={cn(\"p-2.5 rounded-lg w-fit mb-3\", action.color)}>\n {action.icon}\n </div>\n <h3 className=\"font-semibold text-text-primary mb-1\">\n {action.label}\n </h3>\n <p className=\"text-sm text-text-secondary\">\n {action.description}\n </p>\n <ArrowRight\n size={16}\n className=\"absolute top-5 right-5 text-text-secondary opacity-0 group-hover:opacity-100 transition-opacity\"\n />\n </button>\n ))}\n </div>\n\n {/* Active Exports — the single emphasised zone on this page */}\n {activeJobs.length > 0 && (\n <EmphasisPanel\n data-tour=\"export-dashboard-active-section\"\n className=\"p-5 sm:p-6\"\n >\n <div className=\"mb-4\">\n <h2 className=\"text-lg font-semibold text-text-primary\">\n {tr(\"export.dashboard.active.title\", \"Active Exports\")}\n </h2>\n <p className=\"text-sm text-text-secondary\">\n {tr(\n \"export.dashboard.active.description\",\n \"Currently running export jobs\",\n )}\n </p>\n </div>\n <div className=\"space-y-3\">\n {activeJobs.map((job) => (\n <button\n type=\"button\"\n key={job.id}\n onClick={() => handleNavigate(job.id)}\n className={cn(\n \"w-full text-left border border-border-seam rounded-xl p-4 bg-bg-surface/70\",\n \"hover:border-primary/40 transition-colors duration-200\",\n \"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/40\",\n )}\n >\n <div className=\"flex items-center justify-between mb-2\">\n <h4 className=\"font-semibold text-text-primary\">{job.name}</h4>\n <ExportStatusBadge status={job.status} />\n </div>\n <ExportProgressBar progress={job.progress} size=\"sm\" />\n </button>\n ))}\n </div>\n </EmphasisPanel>\n )}\n\n {/* Recent Exports */}\n <PageSection\n data-tour=\"export-dashboard-recent-section\"\n title={tr(\"export.dashboard.recent.title\", \"Recent Exports\")}\n description={tr(\n \"export.dashboard.recent.description\",\n \"Your latest export jobs\",\n )}\n actions={\n recentJobs.length > 0 ? (\n <button\n type=\"button\"\n onClick={() => handleNavigate(\"history\")}\n className=\"text-sm text-primary hover:underline font-medium\"\n >\n {tr(\"export.dashboard.recent.actions.viewAll\", \"View All\")}\n </button>\n ) : undefined\n }\n >\n {isLoading ? (\n <div className=\"space-y-3\">\n {[...Array(3)].map((_, i) => (\n <div\n key={i}\n className=\"border border-border-seam rounded-xl p-4 animate-pulse\"\n >\n <div className=\"flex items-center justify-between mb-2\">\n <div className=\"h-4 w-48 bg-bg-sunken rounded\" />\n <div className=\"h-5 w-20 bg-bg-sunken rounded-full\" />\n </div>\n <div className=\"h-3 w-32 bg-bg-sunken rounded mt-2\" />\n </div>\n ))}\n </div>\n ) : recentJobs.length > 0 ? (\n <div className=\"space-y-3\">\n {recentJobs.map((job, index) => (\n <button\n type=\"button\"\n key={job.id}\n onClick={() => handleNavigate(job.id)}\n className={cn(\n \"w-full text-left border border-border-seam rounded-xl p-4 bg-bg-surface\",\n \"hover:border-primary/40 transition-colors duration-200\",\n \"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/40\",\n \"animate-in fade-in-0\",\n )}\n style={{ animationDelay: `${index * 50}ms` }}\n >\n <div className=\"flex items-start sm:items-center justify-between gap-3\">\n <div className=\"flex-1 min-w-0\">\n <h4 className=\"font-semibold text-text-primary truncate\">\n {job.name}\n </h4>\n <p className=\"text-sm text-text-secondary mt-1 line-clamp-2\">\n {job.entityTypes.join(\", \")} · {job.format}\n {job.totalEntities != null &&\n ` · ${tr(\n \"export.dashboard.recent.entitiesCount\",\n \"{count} entities\",\n { count: job.totalEntities.toLocaleString() },\n )}`}\n </p>\n </div>\n <div className=\"flex items-center gap-2 flex-shrink-0\">\n <ExportStatusBadge status={job.status} />\n <ArrowRight\n size={16}\n className=\"text-text-secondary hidden sm:block\"\n />\n </div>\n </div>\n </button>\n ))}\n </div>\n ) : (\n <EmptyState\n icon={<Download size={48} />}\n title={tr(\"export.dashboard.empty.title\", \"No exports yet\")}\n description={tr(\n \"export.dashboard.empty.description\",\n \"Create your first export to start downloading your workspace data.\",\n )}\n action={\n <button\n type=\"button\"\n onClick={() => handleNavigate(\"new\")}\n className=\"inline-flex items-center gap-2 px-4 py-2 bg-action-primary-bg text-action-primary-text rounded-lg hover:bg-action-primary-bg/90 transition-colors font-medium\"\n >\n <Plus size={16} />\n {tr(\n \"export.dashboard.empty.actions.createFirst\",\n \"Create First Export\",\n )}\n </button>\n }\n />\n )}\n </PageSection>\n </PageLayout>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ExportDashboardPage.js","names":[],"sources":["../../../src/export/pages/ExportDashboardPage.tsx"],"sourcesContent":["import {\n Plus,\n Download,\n Clock,\n FileBox,\n ArrowRight,\n Activity,\n CheckCircle2,\n} from \"lucide-react\";\nimport { useI18n } from \"@burdenoff/fe-libs/shared/providers/shell/I18nProvider\";\nimport {\n GlassCard,\n EmphasisPanel,\n AuroraBackground,\n GradientText,\n IllustratedEmptyState,\n PagePurpose,\n NextSteps,\n type NextStep,\n} from \"@burdenoff/fe-libs/ui\";\nimport { useExport } from \"../providers/ExportProvider\";\nimport { useExportJobs } from \"../hooks/useExportQueries\";\nimport { ExportStatusBadge } from \"../components/ExportStatusBadge\";\nimport { ExportProgressBar } from \"../components/ExportProgressBar\";\nimport { PageLayout, PageSection } from \"../components/PageLayout\";\nimport { cn } from \"../utils/cn\";\nimport { tWithFallback } from \"../utils/i18n\";\n\n/**\n * Helper to join paths correctly, avoiding double slashes\n */\nconst joinPath = (base: string, path: string): string => {\n const cleanBase = base.endsWith(\"/\") ? base.slice(0, -1) : base;\n const cleanPath = path.startsWith(\"/\") ? path : `/${path}`;\n return cleanBase + cleanPath;\n};\n\n/**\n * Export Dashboard Page\n * Overview with recent exports, quick actions, and status summary\n */\nexport function ExportDashboardPage() {\n const { basePath = \"/\", navigate } = useExport();\n const { t } = useI18n();\n const tr = (\n key: string,\n fallback: string,\n params?: Record<string, string | number>,\n ) => tWithFallback(t, key, fallback, params);\n const { data: jobs, isLoading } = useExportJobs({});\n\n const recentJobs = jobs.slice(0, 5);\n const activeJobs = jobs.filter(\n (j) => j.status === \"RUNNING\" || j.status === \"QUEUED\",\n );\n const completedJobs = jobs.filter((j) => j.status === \"COMPLETED\");\n\n const metrics = [\n {\n icon: <Download size={18} />,\n label: tr(\"export.dashboard.metrics.total\", \"Total Exports\"),\n value: jobs.length,\n treatment: \"glass\" as const,\n glow: true,\n },\n {\n icon: <Activity size={18} />,\n label: tr(\"export.dashboard.metrics.active\", \"Active\"),\n value: activeJobs.length,\n treatment: \"metric\" as const,\n glow: false,\n },\n {\n icon: <CheckCircle2 size={18} />,\n label: tr(\"export.dashboard.metrics.completed\", \"Completed\"),\n value: completedJobs.length,\n treatment: \"metric\" as const,\n glow: false,\n },\n ];\n\n const handleNavigate = (path: string) => {\n if (!navigate) return;\n navigate(joinPath(basePath, path));\n };\n\n // New-user orientation: 2–4 concrete next actions wired to real navigation.\n const nextSteps: NextStep[] = [\n {\n id: \"create\",\n label: tr(\n \"export.dashboard.nextSteps.create.label\",\n \"Create your first export\",\n ),\n description: tr(\n \"export.dashboard.nextSteps.create.description\",\n \"Pick the data you want and download it as CSV or JSON.\",\n ),\n icon: <Plus size={16} />,\n onClick: () => handleNavigate(\"new\"),\n done: jobs.length > 0,\n },\n {\n id: \"template\",\n label: tr(\n \"export.dashboard.nextSteps.template.label\",\n \"Save a reusable template\",\n ),\n description: tr(\n \"export.dashboard.nextSteps.template.description\",\n \"Store a common export config so repeat exports are one click.\",\n ),\n icon: <FileBox size={16} />,\n onClick: () => handleNavigate(\"templates\"),\n },\n {\n id: \"history\",\n label: tr(\n \"export.dashboard.nextSteps.history.label\",\n \"Track exports in History\",\n ),\n description: tr(\n \"export.dashboard.nextSteps.history.description\",\n \"Monitor progress and grab download links for finished jobs.\",\n ),\n icon: <Clock size={16} />,\n onClick: () => handleNavigate(\"history\"),\n done: completedJobs.length > 0,\n },\n ];\n\n return (\n <PageLayout showHeader={false}>\n {/* Hero header with living-glass aurora backdrop (primary page only) */}\n <header className=\"relative overflow-hidden rounded-2xl\">\n <AuroraBackground intensity=\"subtle\" />\n <div className=\"relative flex items-center gap-3 px-2 py-4 sm:py-5\">\n <div className=\"flex-shrink-0 p-2.5 rounded-xl bg-action-primary-bg/10 text-primary\">\n <Download size={24} />\n </div>\n <div className=\"space-y-1\">\n <h1 className=\"text-2xl sm:text-3xl font-bold tracking-tight text-text-primary\">\n <GradientText>{tr(\"export.dashboard.title\", \"Export\")}</GradientText>\n </h1>\n <p className=\"text-sm sm:text-base text-text-secondary max-w-2xl\">\n {tr(\n \"export.dashboard.subtitle\",\n \"Export your workspace data in multiple formats\",\n )}\n </p>\n </div>\n </div>\n </header>\n\n {/* Page purpose — plain-language story of what Export is for */}\n <PagePurpose icon={<Download size={16} />}>\n {tr(\n \"export.dashboard.purpose\",\n \"Export takes your workspace data — people, projects, files, tags, activity and more — and packages it into downloadable CSV or JSON files. Use it to back up your data, hand it to another tool, run an audit, or take it with you when you leave. Pick what you want, choose a format, and grab the download when it's ready.\",\n )}\n </PagePurpose>\n\n {/* New-user next steps — dismissable, recommends concrete actions */}\n <NextSteps\n storageKey=\"export-dashboard\"\n title={tr(\"export.dashboard.nextSteps.title\", \"Get started\")}\n steps={nextSteps}\n />\n\n {/* Metric strip */}\n {!isLoading && jobs.length > 0 && (\n <div className=\"grid grid-cols-1 sm:grid-cols-3 gap-4\">\n {metrics.map((m) => (\n <GlassCard\n key={m.label}\n treatment={m.treatment}\n glow={m.glow}\n className=\"p-5 border-border-seam\"\n >\n <div className=\"flex items-center gap-2 text-text-secondary mb-2\">\n {m.icon}\n <span className=\"text-xs font-medium\">{m.label}</span>\n </div>\n <p className=\"text-3xl font-bold tabular-nums text-text-primary\">\n {m.value.toLocaleString()}\n </p>\n </GlassCard>\n ))}\n </div>\n )}\n\n {/* Quick Actions */}\n <div\n className=\"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4\"\n data-tour=\"export-dashboard-quick-actions\"\n >\n {[\n {\n icon: <Plus size={20} />,\n label: tr(\"export.dashboard.actions.newExport.label\", \"New Export\"),\n description: tr(\n \"export.dashboard.actions.newExport.description\",\n \"Create a new data export\",\n ),\n path: \"new\",\n color: \"bg-action-primary-bg/10 text-primary\",\n },\n {\n icon: <Clock size={20} />,\n label: tr(\"export.dashboard.actions.history.label\", \"History\"),\n description: tr(\n \"export.dashboard.actions.history.description\",\n \"View past exports\",\n ),\n path: \"history\",\n color: \"bg-status-info-bg-subtle text-status-info-text\",\n },\n {\n icon: <FileBox size={20} />,\n label: tr(\"export.dashboard.actions.templates.label\", \"Templates\"),\n description: tr(\n \"export.dashboard.actions.templates.description\",\n \"Reusable export configs\",\n ),\n path: \"templates\",\n color: \"bg-accent-purple-subtle text-accent-purple\",\n },\n {\n icon: <Activity size={20} />,\n label: tr(\n \"export.dashboard.actions.activeJobs.label\",\n \"Active Jobs\",\n ),\n description: tr(\n \"export.dashboard.actions.activeJobs.description\",\n \"{count} running\",\n { count: activeJobs.length },\n ),\n path: \"history?status=RUNNING\",\n color: \"bg-status-success-bg-subtle text-status-success-text\",\n },\n ].map((action) => (\n <button\n type=\"button\"\n key={action.path + action.label}\n onClick={() => handleNavigate(action.path)}\n className={cn(\n \"group relative overflow-hidden border border-border-seam rounded-xl p-5\",\n \"bg-bg-surface shadow-[var(--shadow-pop)]\",\n \"hover:border-primary/40 transition-colors duration-200\",\n \"text-left focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/40\",\n )}\n >\n <div className={cn(\"p-2.5 rounded-lg w-fit mb-3\", action.color)}>\n {action.icon}\n </div>\n <h3 className=\"font-semibold text-text-primary mb-1\">\n {action.label}\n </h3>\n <p className=\"text-sm text-text-secondary\">\n {action.description}\n </p>\n <ArrowRight\n size={16}\n className=\"absolute top-5 right-5 text-text-secondary opacity-0 group-hover:opacity-100 transition-opacity\"\n />\n </button>\n ))}\n </div>\n\n {/* Active Exports — the single emphasised zone on this page */}\n {activeJobs.length > 0 && (\n <EmphasisPanel\n data-tour=\"export-dashboard-active-section\"\n className=\"p-5 sm:p-6\"\n >\n <div className=\"mb-4\">\n <h2 className=\"text-lg font-semibold text-text-primary\">\n {tr(\"export.dashboard.active.title\", \"Active Exports\")}\n </h2>\n <p className=\"text-sm text-text-secondary\">\n {tr(\n \"export.dashboard.active.description\",\n \"Currently running export jobs\",\n )}\n </p>\n </div>\n <div className=\"space-y-3\">\n {activeJobs.map((job) => (\n <button\n type=\"button\"\n key={job.id}\n onClick={() => handleNavigate(job.id)}\n className={cn(\n \"w-full text-left border border-border-seam rounded-xl p-4 bg-bg-surface/70\",\n \"hover:border-primary/40 transition-colors duration-200\",\n \"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/40\",\n )}\n >\n <div className=\"flex items-center justify-between mb-2\">\n <h4 className=\"font-semibold text-text-primary\">{job.name}</h4>\n <ExportStatusBadge status={job.status} />\n </div>\n <ExportProgressBar progress={job.progress} size=\"sm\" />\n </button>\n ))}\n </div>\n </EmphasisPanel>\n )}\n\n {/* Recent Exports */}\n <PageSection\n data-tour=\"export-dashboard-recent-section\"\n title={tr(\"export.dashboard.recent.title\", \"Recent Exports\")}\n description={tr(\n \"export.dashboard.recent.description\",\n \"Your latest export jobs\",\n )}\n actions={\n recentJobs.length > 0 ? (\n <button\n type=\"button\"\n onClick={() => handleNavigate(\"history\")}\n className=\"text-sm text-primary hover:underline font-medium\"\n >\n {tr(\"export.dashboard.recent.actions.viewAll\", \"View All\")}\n </button>\n ) : undefined\n }\n >\n {isLoading ? (\n <div className=\"space-y-3\">\n {[...Array(3)].map((_, i) => (\n <div\n key={i}\n className=\"border border-border-seam rounded-xl p-4\"\n >\n <div className=\"flex items-center justify-between mb-2\">\n <div className=\"h-4 w-48 bg-bg-sunken rounded animate-vc-shimmer\" />\n <div className=\"h-5 w-20 bg-bg-sunken rounded-full animate-vc-shimmer\" />\n </div>\n <div className=\"h-3 w-32 bg-bg-sunken rounded mt-2 animate-vc-shimmer\" />\n </div>\n ))}\n </div>\n ) : recentJobs.length > 0 ? (\n <div className=\"space-y-3\">\n {recentJobs.map((job, index) => (\n <button\n type=\"button\"\n key={job.id}\n onClick={() => handleNavigate(job.id)}\n className={cn(\n \"w-full text-left border border-border-seam rounded-xl p-4 bg-bg-surface\",\n \"hover:border-primary/40 transition-colors duration-200\",\n \"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/40\",\n \"animate-in fade-in-0\",\n )}\n style={{ animationDelay: `${index * 50}ms` }}\n >\n <div className=\"flex items-start sm:items-center justify-between gap-3\">\n <div className=\"flex-1 min-w-0\">\n <h4 className=\"font-semibold text-text-primary truncate\">\n {job.name}\n </h4>\n <p className=\"text-sm text-text-secondary mt-1 line-clamp-2\">\n {job.entityTypes.join(\", \")} · {job.format}\n {job.totalEntities != null &&\n ` · ${tr(\n \"export.dashboard.recent.entitiesCount\",\n \"{count} entities\",\n { count: job.totalEntities.toLocaleString() },\n )}`}\n </p>\n </div>\n <div className=\"flex items-center gap-2 flex-shrink-0\">\n <ExportStatusBadge status={job.status} />\n <ArrowRight\n size={16}\n className=\"text-text-secondary hidden sm:block\"\n />\n </div>\n </div>\n </button>\n ))}\n </div>\n ) : (\n <IllustratedEmptyState\n illustration=\"empty-files\"\n title={tr(\"export.dashboard.empty.title\", \"No exports yet\")}\n description={tr(\n \"export.dashboard.empty.description\",\n \"Create your first export to start downloading your workspace data.\",\n )}\n action={\n <button\n type=\"button\"\n onClick={() => handleNavigate(\"new\")}\n className=\"inline-flex items-center gap-2 px-4 py-2 bg-action-primary-bg text-action-primary-text rounded-lg hover:bg-action-primary-bg/90 transition-colors font-medium\"\n >\n <Plus size={16} />\n {tr(\n \"export.dashboard.empty.actions.createFirst\",\n \"Create First Export\",\n )}\n </button>\n }\n />\n )}\n </PageSection>\n </PageLayout>\n );\n}\n"],"mappings":"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"}
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
import { useExport as e } from "../providers/ExportProvider.js";
|
|
2
|
-
import { useCancelExportJob as t, useDeleteExportJob as n, useExportJob as r, useExportJobProgress as
|
|
3
|
-
import { cn as
|
|
4
|
-
import { getArchiveFormatDisplayName as
|
|
5
|
-
import { ExportStatusBadge as
|
|
6
|
-
import { ExportProgressBar as
|
|
7
|
-
import { PageLayout as
|
|
8
|
-
import { nativeImpact as
|
|
9
|
-
import { useState as
|
|
10
|
-
import { AlertCircle as
|
|
11
|
-
import { useNavigate as
|
|
12
|
-
import { jsx as
|
|
13
|
-
import { CTAOverflowMenu as
|
|
2
|
+
import { useCancelExportJob as t, useDeleteExportJob as n, useExportJob as r, useExportJobProgress as ee, useRetryExportJob as te } from "../hooks/useExportQueries.js";
|
|
3
|
+
import { cn as i } from "../utils/cn.js";
|
|
4
|
+
import { getArchiveFormatDisplayName as ne, getFormatDisplayName as re } from "../constants/enums.js";
|
|
5
|
+
import { ExportStatusBadge as a } from "../components/ExportStatusBadge.js";
|
|
6
|
+
import { ExportProgressBar as o } from "../components/ExportProgressBar.js";
|
|
7
|
+
import { PageLayout as s, PageSection as c } from "../components/PageLayout.js";
|
|
8
|
+
import { nativeImpact as l, nativeNotify as u } from "../../utils/nativeBridge.js";
|
|
9
|
+
import { useState as d } from "react";
|
|
10
|
+
import { AlertCircle as f, ArrowLeft as p, CheckCircle2 as m, Clock as h, Download as g, FileDown as ie, FileText as ae, HardDrive as _, Loader2 as v, RotateCcw as y, Trash2 as b, XCircle as x } from "lucide-react";
|
|
11
|
+
import { useNavigate as S, useParams as oe } from "react-router-dom";
|
|
12
|
+
import { jsx as C, jsxs as w } from "react/jsx-runtime";
|
|
13
|
+
import { CTAOverflowMenu as T, GlassCard as E, IllustratedEmptyState as D, NextSteps as O } from "@burdenoff/fe-libs/ui";
|
|
14
14
|
//#region src/export/pages/ExportDetailPage.tsx
|
|
15
15
|
function k(e) {
|
|
16
16
|
if (e === 0) return "0 B";
|
|
@@ -25,150 +25,168 @@ function k(e) {
|
|
|
25
25
|
}
|
|
26
26
|
var A = (e, t) => (e.endsWith("/") ? e.slice(0, -1) : e) + (t.startsWith("/") ? t : `/${t}`);
|
|
27
27
|
function j() {
|
|
28
|
-
let { jobId: j } =
|
|
28
|
+
let { jobId: j } = oe(), { basePath: M = "/", navigate: N } = e(), P = S(), F = () => {
|
|
29
29
|
window.history.length > 1 ? P(-1) : N?.(M);
|
|
30
|
-
}, { data: I, isLoading: L } = r(j), { data: R } =
|
|
30
|
+
}, { data: I, isLoading: L } = r(j), { data: R } = ee(j), [z, B] = d(null), { cancelJob: se, isPending: V } = t(), { deleteJob: H, isPending: U } = n(), { retryJob: W, isPending: G } = te(), K = R ?? I ?? null, q = K?.status === "CREATED" || K?.status === "QUEUED" || K?.status === "RUNNING", J = K?.status === "COMPLETED", ce = K?.status === "FAILED", Y = K?.status === "FAILED" || K?.status === "CANCELLED" || K?.status === "EXPIRED", le = async () => {
|
|
31
31
|
j && B("cancel");
|
|
32
|
-
},
|
|
33
|
-
j && (
|
|
34
|
-
},
|
|
32
|
+
}, ue = async () => {
|
|
33
|
+
j && (l("medium"), B("delete"));
|
|
34
|
+
}, de = async () => {
|
|
35
35
|
if (!(!j || !z)) {
|
|
36
36
|
try {
|
|
37
|
-
z === "cancel" ? await
|
|
37
|
+
z === "cancel" ? await se(j) : (await H(j), N?.(M)), u("success");
|
|
38
38
|
} catch {
|
|
39
|
-
|
|
39
|
+
u("error");
|
|
40
40
|
}
|
|
41
41
|
B(null);
|
|
42
42
|
}
|
|
43
43
|
}, X = async () => {
|
|
44
44
|
if (!j) return;
|
|
45
|
-
let e = await
|
|
45
|
+
let e = await W(j);
|
|
46
46
|
e?.id && N?.(A(M, e.id));
|
|
47
|
-
}, Z =
|
|
48
|
-
if (L) return /* @__PURE__ */
|
|
47
|
+
}, Z = K?.parts.find((e) => e.downloadUrl);
|
|
48
|
+
if (L) return /* @__PURE__ */ w("div", {
|
|
49
49
|
className: "flex flex-col items-center justify-center py-20",
|
|
50
|
-
children: [/* @__PURE__ */
|
|
50
|
+
children: [/* @__PURE__ */ C(v, {
|
|
51
51
|
size: 48,
|
|
52
52
|
className: "animate-spin text-primary"
|
|
53
|
-
}), /* @__PURE__ */
|
|
53
|
+
}), /* @__PURE__ */ C("span", {
|
|
54
54
|
className: "mt-6 text-sm font-medium text-text-secondary",
|
|
55
55
|
children: "Loading export details…"
|
|
56
56
|
})]
|
|
57
57
|
});
|
|
58
|
-
if (!
|
|
58
|
+
if (!K) return /* @__PURE__ */ w(s, {
|
|
59
59
|
showHeader: !1,
|
|
60
|
-
children: [/* @__PURE__ */
|
|
60
|
+
children: [/* @__PURE__ */ w("div", {
|
|
61
61
|
className: "flex items-center gap-3 mb-6",
|
|
62
|
-
children: [/* @__PURE__ */
|
|
62
|
+
children: [/* @__PURE__ */ C("button", {
|
|
63
63
|
type: "button",
|
|
64
64
|
onClick: F,
|
|
65
|
+
"aria-label": "Go back",
|
|
65
66
|
className: "p-2.5 hover:bg-accent rounded-lg transition-all duration-200",
|
|
66
|
-
children: /* @__PURE__ */
|
|
67
|
-
}), /* @__PURE__ */
|
|
67
|
+
children: /* @__PURE__ */ C(p, { size: 20 })
|
|
68
|
+
}), /* @__PURE__ */ C("h1", {
|
|
68
69
|
className: "text-xl font-bold",
|
|
69
70
|
children: "Export Not Found"
|
|
70
71
|
})]
|
|
71
|
-
}), /* @__PURE__ */
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
}),
|
|
82
|
-
/* @__PURE__ */ T("p", {
|
|
83
|
-
className: "text-status-error-text mb-6",
|
|
84
|
-
children: "The export job you are looking for does not exist or has been deleted."
|
|
85
|
-
}),
|
|
86
|
-
/* @__PURE__ */ E("button", {
|
|
87
|
-
type: "button",
|
|
88
|
-
onClick: F,
|
|
89
|
-
className: "inline-flex items-center gap-2 px-6 py-3 bg-action-primary-bg text-action-primary-text rounded-lg hover:bg-action-primary-bg/90 transition-colors font-medium",
|
|
90
|
-
children: [/* @__PURE__ */ T(h, { size: 18 }), "Back to Dashboard"]
|
|
91
|
-
})
|
|
92
|
-
]
|
|
72
|
+
}), /* @__PURE__ */ C(D, {
|
|
73
|
+
illustration: "empty-data",
|
|
74
|
+
title: "Export not found",
|
|
75
|
+
description: "The export job you are looking for does not exist or has been deleted.",
|
|
76
|
+
action: /* @__PURE__ */ w("button", {
|
|
77
|
+
type: "button",
|
|
78
|
+
onClick: F,
|
|
79
|
+
className: "inline-flex items-center gap-2 px-6 py-3 bg-action-primary-bg text-action-primary-text rounded-lg hover:bg-action-primary-bg/90 transition-colors font-medium",
|
|
80
|
+
children: [/* @__PURE__ */ C(p, { size: 18 }), "Back to Dashboard"]
|
|
81
|
+
})
|
|
93
82
|
})]
|
|
94
83
|
});
|
|
95
84
|
let Q = Z ? {
|
|
96
85
|
label: "Download",
|
|
97
|
-
icon: /* @__PURE__ */
|
|
86
|
+
icon: /* @__PURE__ */ C(g, { size: 16 }),
|
|
98
87
|
onSelect: () => {
|
|
99
88
|
Z.downloadUrl && window.location.assign(Z.downloadUrl);
|
|
100
89
|
}
|
|
101
90
|
} : Y ? {
|
|
102
91
|
label: "Retry Export",
|
|
103
|
-
icon: /* @__PURE__ */
|
|
104
|
-
disabled:
|
|
92
|
+
icon: /* @__PURE__ */ C(y, { size: 16 }),
|
|
93
|
+
disabled: G,
|
|
105
94
|
onSelect: () => {
|
|
106
95
|
X();
|
|
107
96
|
}
|
|
108
97
|
} : void 0, $ = [];
|
|
109
|
-
|
|
98
|
+
Y && Z && $.push({
|
|
110
99
|
label: "Retry Export",
|
|
111
|
-
icon: /* @__PURE__ */
|
|
112
|
-
disabled:
|
|
100
|
+
icon: /* @__PURE__ */ C(y, { size: 16 }),
|
|
101
|
+
disabled: G,
|
|
113
102
|
onSelect: () => {
|
|
114
103
|
X();
|
|
115
104
|
}
|
|
116
|
-
}),
|
|
105
|
+
}), q && $.push({
|
|
117
106
|
label: "Cancel Export",
|
|
118
|
-
icon: /* @__PURE__ */
|
|
119
|
-
disabled:
|
|
107
|
+
icon: /* @__PURE__ */ C(x, { size: 16 }),
|
|
108
|
+
disabled: V,
|
|
120
109
|
onSelect: () => {
|
|
121
|
-
|
|
110
|
+
le();
|
|
122
111
|
}
|
|
123
|
-
}),
|
|
112
|
+
}), q || $.push({
|
|
124
113
|
label: "Delete Export",
|
|
125
|
-
icon: /* @__PURE__ */
|
|
114
|
+
icon: /* @__PURE__ */ C(b, { size: 16 }),
|
|
126
115
|
intent: "destructive",
|
|
127
|
-
disabled:
|
|
116
|
+
disabled: U,
|
|
128
117
|
onSelect: () => {
|
|
129
|
-
|
|
118
|
+
ue();
|
|
130
119
|
}
|
|
131
|
-
})
|
|
120
|
+
});
|
|
121
|
+
let fe = [
|
|
122
|
+
{
|
|
123
|
+
id: "download",
|
|
124
|
+
label: "Download your export",
|
|
125
|
+
description: "Grab the generated files below before their download links expire.",
|
|
126
|
+
icon: /* @__PURE__ */ C(g, { size: 16 }),
|
|
127
|
+
onClick: () => {
|
|
128
|
+
Z?.downloadUrl && window.location.assign(Z.downloadUrl);
|
|
129
|
+
},
|
|
130
|
+
done: J
|
|
131
|
+
},
|
|
132
|
+
...Y ? [{
|
|
133
|
+
id: "retry",
|
|
134
|
+
label: "Retry this export",
|
|
135
|
+
description: "This export didn't finish — start a fresh run with the same settings.",
|
|
136
|
+
icon: /* @__PURE__ */ C(y, { size: 16 }),
|
|
137
|
+
onClick: () => {
|
|
138
|
+
X();
|
|
139
|
+
}
|
|
140
|
+
}] : [],
|
|
141
|
+
{
|
|
142
|
+
id: "history",
|
|
143
|
+
label: "Back to History",
|
|
144
|
+
description: "See all your exports and track other jobs in progress.",
|
|
145
|
+
icon: /* @__PURE__ */ C(h, { size: 16 }),
|
|
146
|
+
onClick: () => N?.(M)
|
|
147
|
+
}
|
|
148
|
+
];
|
|
149
|
+
return /* @__PURE__ */ w(s, {
|
|
132
150
|
showHeader: !1,
|
|
133
151
|
children: [
|
|
134
|
-
/* @__PURE__ */
|
|
152
|
+
/* @__PURE__ */ C("div", {
|
|
135
153
|
className: "relative overflow-hidden rounded-xl bg-accent-wash border border-border-seam p-6 shadow-[var(--shadow-pop)]",
|
|
136
|
-
children: /* @__PURE__ */
|
|
154
|
+
children: /* @__PURE__ */ w("div", {
|
|
137
155
|
className: "relative z-10 flex flex-col sm:flex-row sm:items-center gap-4",
|
|
138
156
|
children: [
|
|
139
|
-
/* @__PURE__ */
|
|
157
|
+
/* @__PURE__ */ C("button", {
|
|
140
158
|
type: "button",
|
|
141
159
|
onClick: F,
|
|
142
160
|
"aria-label": "Go back",
|
|
143
161
|
className: "p-2.5 hover:bg-accent rounded-lg transition-colors duration-200 self-start focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/40",
|
|
144
|
-
children: /* @__PURE__ */
|
|
162
|
+
children: /* @__PURE__ */ C(p, { size: 20 })
|
|
145
163
|
}),
|
|
146
|
-
/* @__PURE__ */
|
|
164
|
+
/* @__PURE__ */ w("div", {
|
|
147
165
|
className: "flex items-center gap-3 flex-1 min-w-0",
|
|
148
166
|
children: [
|
|
149
|
-
/* @__PURE__ */
|
|
167
|
+
/* @__PURE__ */ C("div", {
|
|
150
168
|
className: "p-2.5 rounded-lg bg-action-primary-bg/10",
|
|
151
|
-
children: /* @__PURE__ */
|
|
169
|
+
children: /* @__PURE__ */ C(g, {
|
|
152
170
|
size: 24,
|
|
153
171
|
className: "text-primary"
|
|
154
172
|
})
|
|
155
173
|
}),
|
|
156
|
-
/* @__PURE__ */
|
|
174
|
+
/* @__PURE__ */ w("div", {
|
|
157
175
|
className: "flex-1 min-w-0",
|
|
158
|
-
children: [/* @__PURE__ */
|
|
176
|
+
children: [/* @__PURE__ */ C("h1", {
|
|
159
177
|
className: "text-xl sm:text-2xl font-bold truncate",
|
|
160
|
-
children:
|
|
161
|
-
}), /* @__PURE__ */
|
|
178
|
+
children: K.name
|
|
179
|
+
}), /* @__PURE__ */ C("p", {
|
|
162
180
|
className: "text-sm text-text-secondary mt-1",
|
|
163
|
-
children:
|
|
181
|
+
children: K.entityTypes.join(", ")
|
|
164
182
|
})]
|
|
165
183
|
}),
|
|
166
|
-
/* @__PURE__ */
|
|
184
|
+
/* @__PURE__ */ C(a, { status: K.status })
|
|
167
185
|
]
|
|
168
186
|
}),
|
|
169
|
-
(Q || $.length > 0) && /* @__PURE__ */
|
|
187
|
+
(Q || $.length > 0) && /* @__PURE__ */ C("div", {
|
|
170
188
|
className: "flex-shrink-0",
|
|
171
|
-
children: /* @__PURE__ */ T
|
|
189
|
+
children: /* @__PURE__ */ C(T, {
|
|
172
190
|
primary: Q,
|
|
173
191
|
actions: $
|
|
174
192
|
})
|
|
@@ -176,91 +194,96 @@ function j() {
|
|
|
176
194
|
]
|
|
177
195
|
})
|
|
178
196
|
}),
|
|
179
|
-
(
|
|
197
|
+
(K.status === "RUNNING" || K.status === "QUEUED") && /* @__PURE__ */ w("div", {
|
|
180
198
|
className: "border border-border-seam rounded-xl bg-status-info-bg-subtle p-6",
|
|
181
|
-
children: [/* @__PURE__ */
|
|
182
|
-
progress:
|
|
199
|
+
children: [/* @__PURE__ */ C(o, {
|
|
200
|
+
progress: K.progress,
|
|
183
201
|
size: "lg"
|
|
184
|
-
}),
|
|
202
|
+
}), K.processedEntities != null && K.totalEntities != null && /* @__PURE__ */ w("p", {
|
|
185
203
|
className: "text-sm text-text-secondary mt-2",
|
|
186
204
|
children: [
|
|
187
|
-
|
|
205
|
+
K.processedEntities.toLocaleString(),
|
|
188
206
|
" /",
|
|
189
207
|
" ",
|
|
190
|
-
|
|
208
|
+
K.totalEntities.toLocaleString(),
|
|
191
209
|
" entities processed"
|
|
192
210
|
]
|
|
193
211
|
})]
|
|
194
212
|
}),
|
|
195
|
-
|
|
213
|
+
ce && K.errorMessage && /* @__PURE__ */ w("div", {
|
|
196
214
|
className: "border-2 border-border-default rounded-xl bg-status-error-bg-subtle p-6 flex items-start gap-4",
|
|
197
|
-
children: [/* @__PURE__ */
|
|
215
|
+
children: [/* @__PURE__ */ C(f, {
|
|
198
216
|
size: 24,
|
|
199
217
|
className: "text-status-error-text flex-shrink-0 mt-0.5"
|
|
200
|
-
}), /* @__PURE__ */
|
|
218
|
+
}), /* @__PURE__ */ w("div", { children: [/* @__PURE__ */ C("h3", {
|
|
201
219
|
className: "font-semibold text-status-error-text mb-1",
|
|
202
220
|
children: "Export Failed"
|
|
203
|
-
}), /* @__PURE__ */
|
|
221
|
+
}), /* @__PURE__ */ C("p", {
|
|
204
222
|
className: "text-sm text-status-error-text",
|
|
205
|
-
children:
|
|
223
|
+
children: K.errorMessage
|
|
206
224
|
})] })]
|
|
207
225
|
}),
|
|
208
|
-
/* @__PURE__ */
|
|
226
|
+
/* @__PURE__ */ C("div", {
|
|
209
227
|
className: "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4",
|
|
210
228
|
children: [
|
|
211
229
|
{
|
|
212
|
-
icon: /* @__PURE__ */
|
|
230
|
+
icon: /* @__PURE__ */ C(ae, { size: 18 }),
|
|
213
231
|
label: "Format",
|
|
214
|
-
value:
|
|
232
|
+
value: re(K.format)
|
|
215
233
|
},
|
|
216
234
|
{
|
|
217
|
-
icon: /* @__PURE__ */
|
|
235
|
+
icon: /* @__PURE__ */ C(_, { size: 18 }),
|
|
218
236
|
label: "Archive",
|
|
219
|
-
value:
|
|
237
|
+
value: ne(K.archiveFormat)
|
|
220
238
|
},
|
|
221
239
|
{
|
|
222
|
-
icon: /* @__PURE__ */
|
|
240
|
+
icon: /* @__PURE__ */ C(g, { size: 18 }),
|
|
223
241
|
label: "Total Size",
|
|
224
|
-
value:
|
|
242
|
+
value: K.totalSizeBytes == null ? "-" : k(K.totalSizeBytes)
|
|
225
243
|
},
|
|
226
244
|
{
|
|
227
|
-
icon: /* @__PURE__ */
|
|
245
|
+
icon: /* @__PURE__ */ C(h, { size: 18 }),
|
|
228
246
|
label: "Created",
|
|
229
|
-
value: new Date(
|
|
247
|
+
value: new Date(K.createdAt).toLocaleDateString()
|
|
230
248
|
}
|
|
231
|
-
].map((e) => /* @__PURE__ */ E
|
|
249
|
+
].map((e) => /* @__PURE__ */ w(E, {
|
|
232
250
|
treatment: "metric",
|
|
233
251
|
className: "p-4 border-border-seam",
|
|
234
|
-
children: [/* @__PURE__ */
|
|
252
|
+
children: [/* @__PURE__ */ w("div", {
|
|
235
253
|
className: "flex items-center gap-2 text-text-secondary mb-1",
|
|
236
|
-
children: [e.icon, /* @__PURE__ */
|
|
254
|
+
children: [e.icon, /* @__PURE__ */ C("span", {
|
|
237
255
|
className: "text-xs font-medium",
|
|
238
256
|
children: e.label
|
|
239
257
|
})]
|
|
240
|
-
}), /* @__PURE__ */
|
|
258
|
+
}), /* @__PURE__ */ C("p", {
|
|
241
259
|
className: "font-bold text-lg tabular-nums",
|
|
242
260
|
children: e.value
|
|
243
261
|
})]
|
|
244
262
|
}, e.label))
|
|
245
263
|
}),
|
|
246
|
-
|
|
264
|
+
/* @__PURE__ */ C(O, {
|
|
265
|
+
storageKey: `export-detail-${K.id}`,
|
|
266
|
+
title: "What's next",
|
|
267
|
+
steps: fe
|
|
268
|
+
}),
|
|
269
|
+
K.parts.length > 0 && /* @__PURE__ */ C(c, {
|
|
247
270
|
title: "Export Parts",
|
|
248
|
-
description: `${
|
|
249
|
-
children: /* @__PURE__ */
|
|
271
|
+
description: `${K.parts.length} file(s) generated`,
|
|
272
|
+
children: /* @__PURE__ */ C("div", {
|
|
250
273
|
className: "space-y-2",
|
|
251
|
-
children:
|
|
252
|
-
className:
|
|
253
|
-
children: [/* @__PURE__ */
|
|
274
|
+
children: K.parts.map((e) => /* @__PURE__ */ w("div", {
|
|
275
|
+
className: i("border border-border-seam rounded-xl p-4 flex flex-col sm:flex-row sm:items-center sm:justify-between gap-3 bg-bg-surface", "hover:border-primary/40 transition-colors duration-200"),
|
|
276
|
+
children: [/* @__PURE__ */ w("div", {
|
|
254
277
|
className: "flex items-center gap-3 min-w-0",
|
|
255
|
-
children: [/* @__PURE__ */
|
|
278
|
+
children: [/* @__PURE__ */ C(ie, {
|
|
256
279
|
size: 20,
|
|
257
280
|
className: "text-primary flex-shrink-0"
|
|
258
|
-
}), /* @__PURE__ */
|
|
281
|
+
}), /* @__PURE__ */ w("div", {
|
|
259
282
|
className: "min-w-0",
|
|
260
|
-
children: [/* @__PURE__ */
|
|
283
|
+
children: [/* @__PURE__ */ C("p", {
|
|
261
284
|
className: "font-medium truncate",
|
|
262
285
|
children: e.fileName
|
|
263
|
-
}), /* @__PURE__ */
|
|
286
|
+
}), /* @__PURE__ */ w("p", {
|
|
264
287
|
className: "text-sm text-text-secondary",
|
|
265
288
|
children: [
|
|
266
289
|
e.entityTypes.join(", "),
|
|
@@ -271,67 +294,67 @@ function j() {
|
|
|
271
294
|
]
|
|
272
295
|
})]
|
|
273
296
|
})]
|
|
274
|
-
}), /* @__PURE__ */
|
|
297
|
+
}), /* @__PURE__ */ C("div", {
|
|
275
298
|
className: "flex items-center gap-2 flex-shrink-0",
|
|
276
|
-
children: e.downloadUrl ? /* @__PURE__ */
|
|
299
|
+
children: e.downloadUrl ? /* @__PURE__ */ w("a", {
|
|
277
300
|
href: e.downloadUrl,
|
|
278
301
|
className: "inline-flex items-center gap-2 px-3 py-1.5 bg-action-primary-bg text-action-primary-text rounded-lg hover:bg-action-primary-bg/90 transition-colors text-sm font-medium",
|
|
279
|
-
children: [/* @__PURE__ */
|
|
280
|
-
}) : /* @__PURE__ */
|
|
302
|
+
children: [/* @__PURE__ */ C(g, { size: 14 }), "Download"]
|
|
303
|
+
}) : /* @__PURE__ */ w("span", {
|
|
281
304
|
className: "inline-flex items-center gap-1.5 text-sm text-text-secondary",
|
|
282
|
-
children: [/* @__PURE__ */
|
|
305
|
+
children: [/* @__PURE__ */ C(h, { size: 14 }), "Pending"]
|
|
283
306
|
})
|
|
284
307
|
})]
|
|
285
308
|
}, e.id))
|
|
286
309
|
})
|
|
287
310
|
}),
|
|
288
|
-
|
|
311
|
+
J && K.parts.length === 0 && /* @__PURE__ */ w("div", {
|
|
289
312
|
className: "border-2 border-border-default rounded-xl bg-status-success-bg-subtle p-6 text-center",
|
|
290
313
|
children: [
|
|
291
|
-
/* @__PURE__ */
|
|
314
|
+
/* @__PURE__ */ C(m, {
|
|
292
315
|
size: 48,
|
|
293
316
|
className: "text-status-success-text mx-auto mb-3"
|
|
294
317
|
}),
|
|
295
|
-
/* @__PURE__ */
|
|
318
|
+
/* @__PURE__ */ C("h3", {
|
|
296
319
|
className: "text-lg font-bold text-status-success-text mb-1",
|
|
297
320
|
children: "Export Complete"
|
|
298
321
|
}),
|
|
299
|
-
/* @__PURE__ */
|
|
322
|
+
/* @__PURE__ */ C("p", {
|
|
300
323
|
className: "text-sm text-status-success-text",
|
|
301
324
|
children: "Your export has completed but no download parts are available yet."
|
|
302
325
|
})
|
|
303
326
|
]
|
|
304
327
|
}),
|
|
305
|
-
z && /* @__PURE__ */
|
|
328
|
+
z && /* @__PURE__ */ C("div", {
|
|
306
329
|
role: "dialog",
|
|
307
330
|
"aria-modal": "true",
|
|
308
331
|
"aria-labelledby": "export-confirm-title",
|
|
309
332
|
className: "fixed inset-0 z-50 flex items-center justify-center bg-bg-surface/80 backdrop-blur-sm p-4",
|
|
310
|
-
children: /* @__PURE__ */
|
|
333
|
+
children: /* @__PURE__ */ w("div", {
|
|
311
334
|
className: "w-full max-w-md rounded-xl border-2 border-border-subtle bg-bg-surface p-6 shadow-xl",
|
|
312
335
|
children: [
|
|
313
|
-
/* @__PURE__ */
|
|
336
|
+
/* @__PURE__ */ C("h2", {
|
|
314
337
|
id: "export-confirm-title",
|
|
315
338
|
className: "text-lg font-bold",
|
|
316
339
|
children: z === "cancel" ? "Cancel export?" : "Delete export?"
|
|
317
340
|
}),
|
|
318
|
-
/* @__PURE__ */
|
|
341
|
+
/* @__PURE__ */ C("p", {
|
|
319
342
|
className: "mt-2 text-sm text-text-secondary",
|
|
320
343
|
children: z === "cancel" ? "This stops the running export job. You can retry it later if needed." : "This removes the export job from history. This action cannot be undone."
|
|
321
344
|
}),
|
|
322
|
-
/* @__PURE__ */
|
|
345
|
+
/* @__PURE__ */ w("div", {
|
|
323
346
|
className: "mt-6 flex flex-col-reverse sm:flex-row sm:justify-end gap-3",
|
|
324
|
-
children: [/* @__PURE__ */
|
|
347
|
+
children: [/* @__PURE__ */ C("button", {
|
|
325
348
|
type: "button",
|
|
326
349
|
onClick: () => B(null),
|
|
327
350
|
className: "px-4 py-2 rounded-lg border-2 border-border-subtle hover:bg-accent transition-colors font-medium",
|
|
328
351
|
children: "Keep Export"
|
|
329
|
-
}), /* @__PURE__ */
|
|
352
|
+
}), /* @__PURE__ */ w("button", {
|
|
330
353
|
type: "button",
|
|
331
|
-
onClick:
|
|
332
|
-
disabled:
|
|
354
|
+
onClick: de,
|
|
355
|
+
disabled: V || U,
|
|
333
356
|
className: "inline-flex items-center justify-center gap-2 px-4 py-2 rounded-lg bg-status-error-bg text-status-error-text hover:bg-status-error-bg/90 transition-colors font-medium disabled:opacity-50",
|
|
334
|
-
children: [
|
|
357
|
+
children: [V || U ? /* @__PURE__ */ C(v, {
|
|
335
358
|
size: 16,
|
|
336
359
|
className: "animate-spin"
|
|
337
360
|
}) : null, z === "cancel" ? "Cancel Export" : "Delete Export"]
|