@burdenoff/microfe-export 2026.510.111
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/README.md +243 -0
- package/dist/dev/main.d.ts +2 -0
- package/dist/dev/main.d.ts.map +1 -0
- package/dist/export/ExportRoot.d.ts +31 -0
- package/dist/export/ExportRoot.d.ts.map +1 -0
- package/dist/export/ExportRoot.js +70 -0
- package/dist/export/ExportRoot.js.map +1 -0
- package/dist/export/ExportRoutes.d.ts +14 -0
- package/dist/export/ExportRoutes.d.ts.map +1 -0
- package/dist/export/ExportRoutes.js +104 -0
- package/dist/export/ExportRoutes.js.map +1 -0
- package/dist/export/components/ExportProgressBar.d.ts +12 -0
- package/dist/export/components/ExportProgressBar.d.ts.map +1 -0
- package/dist/export/components/ExportProgressBar.js +34 -0
- package/dist/export/components/ExportProgressBar.js.map +1 -0
- package/dist/export/components/ExportStatusBadge.d.ts +12 -0
- package/dist/export/components/ExportStatusBadge.d.ts.map +1 -0
- package/dist/export/components/ExportStatusBadge.js +39 -0
- package/dist/export/components/ExportStatusBadge.js.map +1 -0
- package/dist/export/components/PageLayout.d.ts +55 -0
- package/dist/export/components/PageLayout.d.ts.map +1 -0
- package/dist/export/components/PageLayout.js +93 -0
- package/dist/export/components/PageLayout.js.map +1 -0
- package/dist/export/components/ui.d.ts +6 -0
- package/dist/export/components/ui.d.ts.map +1 -0
- package/dist/export/constants/enums.d.ts +79 -0
- package/dist/export/constants/enums.d.ts.map +1 -0
- package/dist/export/constants/enums.js +27 -0
- package/dist/export/constants/enums.js.map +1 -0
- package/dist/export/constants/index.d.ts +7 -0
- package/dist/export/constants/index.d.ts.map +1 -0
- package/dist/export/hooks/useExportQueries.d.ts +224 -0
- package/dist/export/hooks/useExportQueries.d.ts.map +1 -0
- package/dist/export/hooks/useExportQueries.js +401 -0
- package/dist/export/hooks/useExportQueries.js.map +1 -0
- package/dist/export/index.d.ts +29 -0
- package/dist/export/index.d.ts.map +1 -0
- package/dist/export/index.js +3 -0
- package/dist/export/pages/CreateExportPage.d.ts +2 -0
- package/dist/export/pages/CreateExportPage.d.ts.map +1 -0
- package/dist/export/pages/CreateExportPage.js +495 -0
- package/dist/export/pages/CreateExportPage.js.map +1 -0
- package/dist/export/pages/ExportDashboardPage.d.ts +6 -0
- package/dist/export/pages/ExportDashboardPage.d.ts.map +1 -0
- package/dist/export/pages/ExportDashboardPage.js +166 -0
- package/dist/export/pages/ExportDashboardPage.js.map +1 -0
- package/dist/export/pages/ExportDetailPage.d.ts +7 -0
- package/dist/export/pages/ExportDetailPage.d.ts.map +1 -0
- package/dist/export/pages/ExportDetailPage.js +327 -0
- package/dist/export/pages/ExportDetailPage.js.map +1 -0
- package/dist/export/pages/ExportHistoryPage.d.ts +6 -0
- package/dist/export/pages/ExportHistoryPage.d.ts.map +1 -0
- package/dist/export/pages/ExportHistoryPage.js +261 -0
- package/dist/export/pages/ExportHistoryPage.js.map +1 -0
- package/dist/export/pages/ExportLandingPage.d.ts +9 -0
- package/dist/export/pages/ExportLandingPage.d.ts.map +1 -0
- package/dist/export/pages/ExportLandingPage.js +56 -0
- package/dist/export/pages/ExportLandingPage.js.map +1 -0
- package/dist/export/pages/ExportTemplatesPage.d.ts +6 -0
- package/dist/export/pages/ExportTemplatesPage.d.ts.map +1 -0
- package/dist/export/pages/ExportTemplatesPage.js +343 -0
- package/dist/export/pages/ExportTemplatesPage.js.map +1 -0
- package/dist/export/pages/TemplateDetailPage.d.ts +7 -0
- package/dist/export/pages/TemplateDetailPage.d.ts.map +1 -0
- package/dist/export/pages/TemplateDetailPage.js +215 -0
- package/dist/export/pages/TemplateDetailPage.js.map +1 -0
- package/dist/export/providers/ExportProvider.d.ts +13 -0
- package/dist/export/providers/ExportProvider.d.ts.map +1 -0
- package/dist/export/providers/ExportProvider.js +103 -0
- package/dist/export/providers/ExportProvider.js.map +1 -0
- package/dist/export/store/exportStore.d.ts +17 -0
- package/dist/export/store/exportStore.d.ts.map +1 -0
- package/dist/export/store/exportStore.js +43 -0
- package/dist/export/store/exportStore.js.map +1 -0
- package/dist/export/types/index.d.ts +230 -0
- package/dist/export/types/index.d.ts.map +1 -0
- package/dist/export/utils/cn.d.ts +8 -0
- package/dist/export/utils/cn.d.ts.map +1 -0
- package/dist/export/utils/cn.js +10 -0
- package/dist/export/utils/cn.js.map +1 -0
- package/dist/export/utils/events.d.ts +7 -0
- package/dist/export/utils/events.d.ts.map +1 -0
- package/dist/export/utils/events.js +16 -0
- package/dist/export/utils/events.js.map +1 -0
- package/dist/export/utils/i18n.d.ts +6 -0
- package/dist/export/utils/i18n.d.ts.map +1 -0
- package/dist/export/utils/i18n.js +15 -0
- package/dist/export/utils/i18n.js.map +1 -0
- package/dist/generated/global-operations.d.ts +2 -0
- package/dist/generated/global-operations.d.ts.map +1 -0
- package/dist/generated/global-types.d.ts +21253 -0
- package/dist/generated/global-types.d.ts.map +1 -0
- package/dist/generated/wspace-operations.d.ts +773 -0
- package/dist/generated/wspace-operations.d.ts.map +1 -0
- package/dist/generated/wspace-operations.js +319 -0
- package/dist/generated/wspace-operations.js.map +1 -0
- package/dist/generated/wspace-types.d.ts +55214 -0
- package/dist/generated/wspace-types.d.ts.map +1 -0
- package/dist/generated/wspace-types.js +12 -0
- package/dist/generated/wspace-types.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +5 -0
- package/dist/node_modules/@apollo/client/errors/CombinedGraphQLErrors.js +24 -0
- package/dist/node_modules/@apollo/client/errors/CombinedGraphQLErrors.js.map +1 -0
- package/dist/node_modules/@apollo/client/errors/utils.js +16 -0
- package/dist/node_modules/@apollo/client/errors/utils.js.map +1 -0
- package/dist/node_modules/@apollo/client/link/core/ApolloLink.js +52 -0
- package/dist/node_modules/@apollo/client/link/core/ApolloLink.js.map +1 -0
- package/dist/node_modules/@apollo/client/link/subscriptions/index.js +41 -0
- package/dist/node_modules/@apollo/client/link/subscriptions/index.js.map +1 -0
- package/dist/node_modules/@apollo/client/link/utils/createOperation.js +34 -0
- package/dist/node_modules/@apollo/client/link/utils/createOperation.js.map +1 -0
- package/dist/node_modules/@apollo/client/utilities/caching/sizes.js +6 -0
- package/dist/node_modules/@apollo/client/utilities/caching/sizes.js.map +1 -0
- package/dist/node_modules/@apollo/client/utilities/graphql/print.js +16 -0
- package/dist/node_modules/@apollo/client/utilities/graphql/print.js.map +1 -0
- package/dist/node_modules/@apollo/client/utilities/internal/caches.js +19 -0
- package/dist/node_modules/@apollo/client/utilities/internal/caches.js.map +1 -0
- package/dist/node_modules/@apollo/client/utilities/internal/checkDocument.js +21 -0
- package/dist/node_modules/@apollo/client/utilities/internal/checkDocument.js.map +1 -0
- package/dist/node_modules/@apollo/client/utilities/internal/getMainDefinition.js +17 -0
- package/dist/node_modules/@apollo/client/utilities/internal/getMainDefinition.js.map +1 -0
- package/dist/node_modules/@apollo/client/utilities/internal/getMemoryInternals.js +9 -0
- package/dist/node_modules/@apollo/client/utilities/internal/getMemoryInternals.js.map +1 -0
- package/dist/node_modules/@apollo/client/utilities/internal/getOperationDefinition.js +9 -0
- package/dist/node_modules/@apollo/client/utilities/internal/getOperationDefinition.js.map +1 -0
- package/dist/node_modules/@apollo/client/utilities/internal/getOperationName.js +8 -0
- package/dist/node_modules/@apollo/client/utilities/internal/getOperationName.js.map +1 -0
- package/dist/node_modules/@apollo/client/utilities/internal/globals/global.js +9 -0
- package/dist/node_modules/@apollo/client/utilities/internal/globals/global.js.map +1 -0
- package/dist/node_modules/@apollo/client/utilities/internal/globals/maybe.js +10 -0
- package/dist/node_modules/@apollo/client/utilities/internal/globals/maybe.js.map +1 -0
- package/dist/node_modules/@apollo/client/utilities/internal/isNonNullObject.js +8 -0
- package/dist/node_modules/@apollo/client/utilities/internal/isNonNullObject.js.map +1 -0
- package/dist/node_modules/@apollo/client/utilities/internal/makeUniqueId.js +10 -0
- package/dist/node_modules/@apollo/client/utilities/internal/makeUniqueId.js.map +1 -0
- package/dist/node_modules/@apollo/client/utilities/internal/memoize.js +23 -0
- package/dist/node_modules/@apollo/client/utilities/internal/memoize.js.map +1 -0
- package/dist/node_modules/@apollo/client/utilities/internal/stringifyForDisplay.js +10 -0
- package/dist/node_modules/@apollo/client/utilities/internal/stringifyForDisplay.js.map +1 -0
- package/dist/node_modules/@apollo/client/utilities/invariant/index.js +57 -0
- package/dist/node_modules/@apollo/client/utilities/invariant/index.js.map +1 -0
- package/dist/node_modules/@apollo/client/version.js +6 -0
- package/dist/node_modules/@apollo/client/version.js.map +1 -0
- package/dist/node_modules/@wry/caches/lib/weak.js +67 -0
- package/dist/node_modules/@wry/caches/lib/weak.js.map +1 -0
- package/dist/node_modules/@wry/trie/lib/index.js +53 -0
- package/dist/node_modules/@wry/trie/lib/index.js.map +1 -0
- package/dist/node_modules/clsx/dist/clsx.js +18 -0
- package/dist/node_modules/clsx/dist/clsx.js.map +1 -0
- package/dist/node_modules/graphql-ws/dist/client.js +272 -0
- package/dist/node_modules/graphql-ws/dist/client.js.map +1 -0
- package/dist/node_modules/graphql-ws/dist/common-CGW11Fyb.js +62 -0
- package/dist/node_modules/graphql-ws/dist/common-CGW11Fyb.js.map +1 -0
- package/dist/node_modules/rxjs/dist/esm5/internal/NotificationFactories.js +21 -0
- package/dist/node_modules/rxjs/dist/esm5/internal/NotificationFactories.js.map +1 -0
- package/dist/node_modules/rxjs/dist/esm5/internal/Observable.js +78 -0
- package/dist/node_modules/rxjs/dist/esm5/internal/Observable.js.map +1 -0
- package/dist/node_modules/rxjs/dist/esm5/internal/Subscriber.js +117 -0
- package/dist/node_modules/rxjs/dist/esm5/internal/Subscriber.js.map +1 -0
- package/dist/node_modules/rxjs/dist/esm5/internal/Subscription.js +93 -0
- package/dist/node_modules/rxjs/dist/esm5/internal/Subscription.js.map +1 -0
- package/dist/node_modules/rxjs/dist/esm5/internal/config.js +12 -0
- package/dist/node_modules/rxjs/dist/esm5/internal/config.js.map +1 -0
- package/dist/node_modules/rxjs/dist/esm5/internal/observable/empty.js +9 -0
- package/dist/node_modules/rxjs/dist/esm5/internal/observable/empty.js.map +1 -0
- package/dist/node_modules/rxjs/dist/esm5/internal/scheduler/timeoutProvider.js +16 -0
- package/dist/node_modules/rxjs/dist/esm5/internal/scheduler/timeoutProvider.js.map +1 -0
- package/dist/node_modules/rxjs/dist/esm5/internal/symbol/observable.js +8 -0
- package/dist/node_modules/rxjs/dist/esm5/internal/symbol/observable.js.map +1 -0
- package/dist/node_modules/rxjs/dist/esm5/internal/util/UnsubscriptionError.js +13 -0
- package/dist/node_modules/rxjs/dist/esm5/internal/util/UnsubscriptionError.js.map +1 -0
- package/dist/node_modules/rxjs/dist/esm5/internal/util/arrRemove.js +11 -0
- package/dist/node_modules/rxjs/dist/esm5/internal/util/arrRemove.js.map +1 -0
- package/dist/node_modules/rxjs/dist/esm5/internal/util/createErrorClass.js +11 -0
- package/dist/node_modules/rxjs/dist/esm5/internal/util/createErrorClass.js.map +1 -0
- package/dist/node_modules/rxjs/dist/esm5/internal/util/errorContext.js +22 -0
- package/dist/node_modules/rxjs/dist/esm5/internal/util/errorContext.js.map +1 -0
- package/dist/node_modules/rxjs/dist/esm5/internal/util/identity.js +8 -0
- package/dist/node_modules/rxjs/dist/esm5/internal/util/identity.js.map +1 -0
- package/dist/node_modules/rxjs/dist/esm5/internal/util/isFunction.js +8 -0
- package/dist/node_modules/rxjs/dist/esm5/internal/util/isFunction.js.map +1 -0
- package/dist/node_modules/rxjs/dist/esm5/internal/util/noop.js +6 -0
- package/dist/node_modules/rxjs/dist/esm5/internal/util/noop.js.map +1 -0
- package/dist/node_modules/rxjs/dist/esm5/internal/util/pipe.js +13 -0
- package/dist/node_modules/rxjs/dist/esm5/internal/util/pipe.js.map +1 -0
- package/dist/node_modules/rxjs/dist/esm5/internal/util/reportUnhandledError.js +14 -0
- package/dist/node_modules/rxjs/dist/esm5/internal/util/reportUnhandledError.js.map +1 -0
- package/dist/node_modules/rxjs/node_modules/tslib/tslib.es6.js +52 -0
- package/dist/node_modules/rxjs/node_modules/tslib/tslib.es6.js.map +1 -0
- package/dist/node_modules/tailwind-merge/dist/bundle-mjs.js +1674 -0
- package/dist/node_modules/tailwind-merge/dist/bundle-mjs.js.map +1 -0
- package/dist/utils/nativeBridge.d.ts +3 -0
- package/dist/utils/nativeBridge.d.ts.map +1 -0
- package/dist/utils/nativeBridge.js +2 -0
- package/package.json +107 -0
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
import { useExport as e } from "../providers/ExportProvider.js";
|
|
2
|
+
import { useExportJobs as t } from "../hooks/useExportQueries.js";
|
|
3
|
+
import { cn as n } from "../utils/cn.js";
|
|
4
|
+
import { tWithFallback as r } from "../utils/i18n.js";
|
|
5
|
+
import { ExportStatusBadge as i } from "../components/ExportStatusBadge.js";
|
|
6
|
+
import { ExportProgressBar as a } from "../components/ExportProgressBar.js";
|
|
7
|
+
import { EmptyState as o, PageLayout as s, PageSection as c } from "../components/PageLayout.js";
|
|
8
|
+
import { Activity as l, ArrowRight as u, Clock as d, Download as f, FileBox as p, Plus as m } from "lucide-react";
|
|
9
|
+
import { jsx as h, jsxs as g } from "react/jsx-runtime";
|
|
10
|
+
import { useI18n as _ } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
|
|
11
|
+
//#region src/export/pages/ExportDashboardPage.tsx
|
|
12
|
+
var v = (e, t) => (e.endsWith("/") ? e.slice(0, -1) : e) + (t.startsWith("/") ? t : `/${t}`);
|
|
13
|
+
function y() {
|
|
14
|
+
let { basePath: y = "/", navigate: b } = e(), { t: x } = _(), S = (e, t, n) => r(x, e, t, n), { data: C, isLoading: w } = t({}), T = C.slice(0, 5), E = C.filter((e) => e.status === "RUNNING" || e.status === "QUEUED"), D = (e) => {
|
|
15
|
+
b && b(v(y, e));
|
|
16
|
+
};
|
|
17
|
+
return /* @__PURE__ */ g(s, {
|
|
18
|
+
title: S("export.dashboard.title", "Export"),
|
|
19
|
+
subtitle: S("export.dashboard.subtitle", "Export your workspace data in multiple formats"),
|
|
20
|
+
icon: /* @__PURE__ */ h(f, { size: 24 }),
|
|
21
|
+
children: [
|
|
22
|
+
/* @__PURE__ */ h("div", {
|
|
23
|
+
className: "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4",
|
|
24
|
+
children: [
|
|
25
|
+
{
|
|
26
|
+
icon: /* @__PURE__ */ h(m, { size: 20 }),
|
|
27
|
+
label: S("export.dashboard.actions.newExport.label", "New Export"),
|
|
28
|
+
description: S("export.dashboard.actions.newExport.description", "Create a new data export"),
|
|
29
|
+
path: "new",
|
|
30
|
+
color: "bg-primary/10 text-primary"
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
icon: /* @__PURE__ */ h(d, { size: 20 }),
|
|
34
|
+
label: S("export.dashboard.actions.history.label", "History"),
|
|
35
|
+
description: S("export.dashboard.actions.history.description", "View past exports"),
|
|
36
|
+
path: "history",
|
|
37
|
+
color: "bg-status-info-bg-subtle text-status-info-text"
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
icon: /* @__PURE__ */ h(p, { size: 20 }),
|
|
41
|
+
label: S("export.dashboard.actions.templates.label", "Templates"),
|
|
42
|
+
description: S("export.dashboard.actions.templates.description", "Reusable export configs"),
|
|
43
|
+
path: "templates",
|
|
44
|
+
color: "bg-accent-purple-subtle text-accent-purple"
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
icon: /* @__PURE__ */ h(l, { size: 20 }),
|
|
48
|
+
label: S("export.dashboard.actions.activeJobs.label", "Active Jobs"),
|
|
49
|
+
description: S("export.dashboard.actions.activeJobs.description", "{count} running", { count: E.length }),
|
|
50
|
+
path: "history?status=RUNNING",
|
|
51
|
+
color: "bg-status-success-bg-subtle text-status-success-text"
|
|
52
|
+
}
|
|
53
|
+
].map((e) => /* @__PURE__ */ g("button", {
|
|
54
|
+
onClick: () => D(e.path),
|
|
55
|
+
className: n("group relative overflow-hidden border-2 border-border/50 rounded-xl p-5", "bg-gradient-to-br from-card/50 to-background shadow-sm", "hover:shadow-md hover:border-primary/30 transition-all duration-200", "text-left"),
|
|
56
|
+
children: [
|
|
57
|
+
/* @__PURE__ */ h("div", {
|
|
58
|
+
className: n("p-2.5 rounded-lg w-fit mb-3", e.color),
|
|
59
|
+
children: e.icon
|
|
60
|
+
}),
|
|
61
|
+
/* @__PURE__ */ h("h3", {
|
|
62
|
+
className: "font-semibold text-foreground mb-1",
|
|
63
|
+
children: e.label
|
|
64
|
+
}),
|
|
65
|
+
/* @__PURE__ */ h("p", {
|
|
66
|
+
className: "text-sm text-muted-foreground",
|
|
67
|
+
children: e.description
|
|
68
|
+
}),
|
|
69
|
+
/* @__PURE__ */ h(u, {
|
|
70
|
+
size: 16,
|
|
71
|
+
className: "absolute top-5 right-5 text-muted-foreground opacity-0 group-hover:opacity-100 transition-opacity"
|
|
72
|
+
})
|
|
73
|
+
]
|
|
74
|
+
}, e.path + e.label))
|
|
75
|
+
}),
|
|
76
|
+
E.length > 0 && /* @__PURE__ */ h(c, {
|
|
77
|
+
title: S("export.dashboard.active.title", "Active Exports"),
|
|
78
|
+
description: S("export.dashboard.active.description", "Currently running export jobs"),
|
|
79
|
+
children: /* @__PURE__ */ h("div", {
|
|
80
|
+
className: "space-y-3",
|
|
81
|
+
children: E.map((e) => /* @__PURE__ */ g("button", {
|
|
82
|
+
onClick: () => D(e.id),
|
|
83
|
+
className: n("w-full text-left border-2 border-border/50 rounded-xl p-4", "hover:shadow-md hover:border-primary/30 transition-all duration-200", "bg-gradient-to-r from-card/50 to-background"),
|
|
84
|
+
children: [/* @__PURE__ */ g("div", {
|
|
85
|
+
className: "flex items-center justify-between mb-2",
|
|
86
|
+
children: [/* @__PURE__ */ h("h4", {
|
|
87
|
+
className: "font-semibold text-foreground",
|
|
88
|
+
children: e.name
|
|
89
|
+
}), /* @__PURE__ */ h(i, { status: e.status })]
|
|
90
|
+
}), /* @__PURE__ */ h(a, {
|
|
91
|
+
progress: e.progress,
|
|
92
|
+
size: "sm"
|
|
93
|
+
})]
|
|
94
|
+
}, e.id))
|
|
95
|
+
})
|
|
96
|
+
}),
|
|
97
|
+
/* @__PURE__ */ h(c, {
|
|
98
|
+
title: S("export.dashboard.recent.title", "Recent Exports"),
|
|
99
|
+
description: S("export.dashboard.recent.description", "Your latest export jobs"),
|
|
100
|
+
actions: T.length > 0 ? /* @__PURE__ */ h("button", {
|
|
101
|
+
onClick: () => D("history"),
|
|
102
|
+
className: "text-sm text-primary hover:underline font-medium",
|
|
103
|
+
children: S("export.dashboard.recent.actions.viewAll", "View All")
|
|
104
|
+
}) : void 0,
|
|
105
|
+
children: w ? /* @__PURE__ */ h("div", {
|
|
106
|
+
className: "space-y-3",
|
|
107
|
+
children: [...[
|
|
108
|
+
,
|
|
109
|
+
,
|
|
110
|
+
,
|
|
111
|
+
]].map((e, t) => /* @__PURE__ */ g("div", {
|
|
112
|
+
className: "border-2 border-border/50 rounded-xl p-4 animate-pulse",
|
|
113
|
+
children: [/* @__PURE__ */ g("div", {
|
|
114
|
+
className: "flex items-center justify-between mb-2",
|
|
115
|
+
children: [/* @__PURE__ */ h("div", { className: "h-4 w-48 bg-muted rounded" }), /* @__PURE__ */ h("div", { className: "h-5 w-20 bg-muted rounded-full" })]
|
|
116
|
+
}), /* @__PURE__ */ h("div", { className: "h-3 w-32 bg-muted rounded mt-2" })]
|
|
117
|
+
}, t))
|
|
118
|
+
}) : T.length > 0 ? /* @__PURE__ */ h("div", {
|
|
119
|
+
className: "space-y-3",
|
|
120
|
+
children: T.map((e, t) => /* @__PURE__ */ h("button", {
|
|
121
|
+
onClick: () => D(e.id),
|
|
122
|
+
className: n("w-full text-left border-2 border-border/50 rounded-xl p-4", "hover:shadow-md hover:border-primary/30 transition-all duration-200", "bg-gradient-to-r from-card/50 to-background", "animate-in fade-in-0 slide-in-from-bottom-2"),
|
|
123
|
+
style: { animationDelay: `${t * 50}ms` },
|
|
124
|
+
children: /* @__PURE__ */ g("div", {
|
|
125
|
+
className: "flex items-start sm:items-center justify-between gap-3",
|
|
126
|
+
children: [/* @__PURE__ */ g("div", {
|
|
127
|
+
className: "flex-1 min-w-0",
|
|
128
|
+
children: [/* @__PURE__ */ h("h4", {
|
|
129
|
+
className: "font-semibold text-foreground truncate",
|
|
130
|
+
children: e.name
|
|
131
|
+
}), /* @__PURE__ */ g("p", {
|
|
132
|
+
className: "text-sm text-muted-foreground mt-1 line-clamp-2",
|
|
133
|
+
children: [
|
|
134
|
+
e.entityTypes.join(", "),
|
|
135
|
+
" · ",
|
|
136
|
+
e.format,
|
|
137
|
+
e.totalEntities != null && ` · ${S("export.dashboard.recent.entitiesCount", "{count} entities", { count: e.totalEntities.toLocaleString() })}`
|
|
138
|
+
]
|
|
139
|
+
})]
|
|
140
|
+
}), /* @__PURE__ */ g("div", {
|
|
141
|
+
className: "flex items-center gap-2 flex-shrink-0",
|
|
142
|
+
children: [/* @__PURE__ */ h(i, { status: e.status }), /* @__PURE__ */ h(u, {
|
|
143
|
+
size: 16,
|
|
144
|
+
className: "text-muted-foreground hidden sm:block"
|
|
145
|
+
})]
|
|
146
|
+
})]
|
|
147
|
+
})
|
|
148
|
+
}, e.id))
|
|
149
|
+
}) : /* @__PURE__ */ h(o, {
|
|
150
|
+
icon: /* @__PURE__ */ h(f, { size: 48 }),
|
|
151
|
+
title: S("export.dashboard.empty.title", "No exports yet"),
|
|
152
|
+
description: S("export.dashboard.empty.description", "Create your first export to start downloading your workspace data."),
|
|
153
|
+
action: /* @__PURE__ */ g("button", {
|
|
154
|
+
onClick: () => D("new"),
|
|
155
|
+
className: "inline-flex items-center gap-2 px-4 py-2 bg-primary text-primary-foreground rounded-lg hover:bg-primary/90 transition-colors font-medium",
|
|
156
|
+
children: [/* @__PURE__ */ h(m, { size: 16 }), S("export.dashboard.empty.actions.createFirst", "Create First Export")]
|
|
157
|
+
})
|
|
158
|
+
})
|
|
159
|
+
})
|
|
160
|
+
]
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
//#endregion
|
|
164
|
+
export { y as ExportDashboardPage };
|
|
165
|
+
|
|
166
|
+
//# sourceMappingURL=ExportDashboardPage.js.map
|
|
@@ -0,0 +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} from \"lucide-react\";\nimport { useI18n } from \"@burdenoff/fe-libs/shared/providers/shell/I18nProvider\";\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\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 {/* Quick Actions */}\n <div className=\"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4\">\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-primary/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 key={action.path + action.label}\n onClick={() => handleNavigate(action.path)}\n className={cn(\n \"group relative overflow-hidden border-2 border-border/50 rounded-xl p-5\",\n \"bg-gradient-to-br from-card/50 to-background shadow-sm\",\n \"hover:shadow-md hover:border-primary/30 transition-all duration-200\",\n \"text-left\",\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-foreground mb-1\">\n {action.label}\n </h3>\n <p className=\"text-sm text-muted-foreground\">\n {action.description}\n </p>\n <ArrowRight\n size={16}\n className=\"absolute top-5 right-5 text-muted-foreground opacity-0 group-hover:opacity-100 transition-opacity\"\n />\n </button>\n ))}\n </div>\n\n {/* Active Exports */}\n {activeJobs.length > 0 && (\n <PageSection\n title={tr(\"export.dashboard.active.title\", \"Active Exports\")}\n description={tr(\n \"export.dashboard.active.description\",\n \"Currently running export jobs\",\n )}\n >\n <div className=\"space-y-3\">\n {activeJobs.map((job) => (\n <button\n key={job.id}\n onClick={() => handleNavigate(job.id)}\n className={cn(\n \"w-full text-left border-2 border-border/50 rounded-xl p-4\",\n \"hover:shadow-md hover:border-primary/30 transition-all duration-200\",\n \"bg-gradient-to-r from-card/50 to-background\",\n )}\n >\n <div className=\"flex items-center justify-between mb-2\">\n <h4 className=\"font-semibold text-foreground\">{job.name}</h4>\n <ExportStatusBadge status={job.status} />\n </div>\n <ExportProgressBar progress={job.progress} size=\"sm\" />\n </button>\n ))}\n </div>\n </PageSection>\n )}\n\n {/* Recent Exports */}\n <PageSection\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 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-2 border-border/50 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-muted rounded\" />\n <div className=\"h-5 w-20 bg-muted rounded-full\" />\n </div>\n <div className=\"h-3 w-32 bg-muted 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 key={job.id}\n onClick={() => handleNavigate(job.id)}\n className={cn(\n \"w-full text-left border-2 border-border/50 rounded-xl p-4\",\n \"hover:shadow-md hover:border-primary/30 transition-all duration-200\",\n \"bg-gradient-to-r from-card/50 to-background\",\n \"animate-in fade-in-0 slide-in-from-bottom-2\",\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-foreground truncate\">\n {job.name}\n </h4>\n <p className=\"text-sm text-muted-foreground 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-muted-foreground 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 onClick={() => handleNavigate(\"new\")}\n className=\"inline-flex items-center gap-2 px-4 py-2 bg-primary text-primary-foreground rounded-lg hover:bg-primary/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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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Export Detail Page
|
|
3
|
+
* Single export job detail view with parts, progress, download links.
|
|
4
|
+
* Uses GraphQL subscriptions for live progress updates when a job is active.
|
|
5
|
+
*/
|
|
6
|
+
export declare function ExportDetailPage(): import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
//# sourceMappingURL=ExportDetailPage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ExportDetailPage.d.ts","sourceRoot":"","sources":["../../../src/export/pages/ExportDetailPage.tsx"],"names":[],"mappings":"AAsDA;;;;GAIG;AACH,wBAAgB,gBAAgB,4CAsX/B"}
|
|
@@ -0,0 +1,327 @@
|
|
|
1
|
+
import { useExport as e } from "../providers/ExportProvider.js";
|
|
2
|
+
import { useCancelExportJob as t, useDeleteExportJob as n, useExportJob as r, useExportJobProgress as i, useRetryExportJob as a } from "../hooks/useExportQueries.js";
|
|
3
|
+
import { cn as o } from "../utils/cn.js";
|
|
4
|
+
import { getArchiveFormatDisplayName as s, getFormatDisplayName as c } from "../constants/enums.js";
|
|
5
|
+
import { ExportStatusBadge as l } from "../components/ExportStatusBadge.js";
|
|
6
|
+
import { ExportProgressBar as u } from "../components/ExportProgressBar.js";
|
|
7
|
+
import { PageLayout as d, PageSection as f } from "../components/PageLayout.js";
|
|
8
|
+
import { nativeImpact as p, nativeNotify as m } from "../../utils/nativeBridge.js";
|
|
9
|
+
import { useState as h } from "react";
|
|
10
|
+
import { AlertCircle as g, ArrowLeft as _, CheckCircle2 as v, Clock as y, Download as b, FileDown as x, FileText as S, HardDrive as C, Loader2 as w, RotateCcw as T, Trash2 as E, XCircle as D } from "lucide-react";
|
|
11
|
+
import { useNavigate as O, useParams as k } from "react-router-dom";
|
|
12
|
+
import { jsx as A, jsxs as j } from "react/jsx-runtime";
|
|
13
|
+
//#region src/export/pages/ExportDetailPage.tsx
|
|
14
|
+
function M(e) {
|
|
15
|
+
if (e === 0) return "0 B";
|
|
16
|
+
let t = 1024, n = [
|
|
17
|
+
"B",
|
|
18
|
+
"KB",
|
|
19
|
+
"MB",
|
|
20
|
+
"GB",
|
|
21
|
+
"TB"
|
|
22
|
+
], r = Math.floor(Math.log(e) / Math.log(t));
|
|
23
|
+
return `${parseFloat((e / t ** +r).toFixed(2))} ${n[r]}`;
|
|
24
|
+
}
|
|
25
|
+
var N = (e, t) => (e.endsWith("/") ? e.slice(0, -1) : e) + (t.startsWith("/") ? t : `/${t}`);
|
|
26
|
+
function P() {
|
|
27
|
+
let { jobId: P } = k(), { basePath: F = "/", navigate: I } = e(), L = O(), R = () => {
|
|
28
|
+
window.history.length > 1 ? L(-1) : I?.(F);
|
|
29
|
+
}, { data: z, isLoading: B } = r(P), { data: V } = i(P), [H, U] = h(null), { cancelJob: W, isPending: G } = t(), { deleteJob: K, isPending: q } = n(), { retryJob: J, isPending: Y } = a(), X = V ?? z ?? null, Z = X?.status === "CREATED" || X?.status === "QUEUED" || X?.status === "RUNNING", Q = X?.status === "COMPLETED", $ = X?.status === "FAILED", ee = X?.status === "FAILED" || X?.status === "CANCELLED" || X?.status === "EXPIRED";
|
|
30
|
+
return B ? /* @__PURE__ */ j("div", {
|
|
31
|
+
className: "flex flex-col items-center justify-center py-20",
|
|
32
|
+
children: [/* @__PURE__ */ A(w, {
|
|
33
|
+
size: 48,
|
|
34
|
+
className: "animate-spin text-primary"
|
|
35
|
+
}), /* @__PURE__ */ A("span", {
|
|
36
|
+
className: "mt-6 text-sm font-medium text-muted-foreground",
|
|
37
|
+
children: "Loading export details..."
|
|
38
|
+
})]
|
|
39
|
+
}) : X ? /* @__PURE__ */ j(d, {
|
|
40
|
+
showHeader: !1,
|
|
41
|
+
children: [
|
|
42
|
+
/* @__PURE__ */ A("div", {
|
|
43
|
+
className: "relative overflow-hidden rounded-xl bg-gradient-to-br from-primary/5 via-primary/3 to-background border border-border/50 p-6 shadow-sm",
|
|
44
|
+
children: /* @__PURE__ */ j("div", {
|
|
45
|
+
className: "relative z-10 flex items-center gap-4",
|
|
46
|
+
children: [/* @__PURE__ */ A("button", {
|
|
47
|
+
onClick: R,
|
|
48
|
+
className: "p-2.5 hover:bg-accent rounded-lg transition-all duration-200",
|
|
49
|
+
children: /* @__PURE__ */ A(_, { size: 20 })
|
|
50
|
+
}), /* @__PURE__ */ j("div", {
|
|
51
|
+
className: "flex items-center gap-3 flex-1",
|
|
52
|
+
children: [
|
|
53
|
+
/* @__PURE__ */ A("div", {
|
|
54
|
+
className: "p-2.5 rounded-lg bg-primary/10",
|
|
55
|
+
children: /* @__PURE__ */ A(b, {
|
|
56
|
+
size: 24,
|
|
57
|
+
className: "text-primary"
|
|
58
|
+
})
|
|
59
|
+
}),
|
|
60
|
+
/* @__PURE__ */ j("div", {
|
|
61
|
+
className: "flex-1 min-w-0",
|
|
62
|
+
children: [/* @__PURE__ */ A("h1", {
|
|
63
|
+
className: "text-xl sm:text-2xl font-bold truncate",
|
|
64
|
+
children: X.name
|
|
65
|
+
}), /* @__PURE__ */ A("p", {
|
|
66
|
+
className: "text-sm text-muted-foreground mt-1",
|
|
67
|
+
children: X.entityTypes.join(", ")
|
|
68
|
+
})]
|
|
69
|
+
}),
|
|
70
|
+
/* @__PURE__ */ A(l, { status: X.status })
|
|
71
|
+
]
|
|
72
|
+
})]
|
|
73
|
+
})
|
|
74
|
+
}),
|
|
75
|
+
(X.status === "RUNNING" || X.status === "QUEUED") && /* @__PURE__ */ j("div", {
|
|
76
|
+
className: "border-2 border-border-default rounded-xl bg-status-info-bg-subtle p-6",
|
|
77
|
+
children: [/* @__PURE__ */ A(u, {
|
|
78
|
+
progress: X.progress,
|
|
79
|
+
size: "lg"
|
|
80
|
+
}), X.processedEntities != null && X.totalEntities != null && /* @__PURE__ */ j("p", {
|
|
81
|
+
className: "text-sm text-muted-foreground mt-2",
|
|
82
|
+
children: [
|
|
83
|
+
X.processedEntities.toLocaleString(),
|
|
84
|
+
" /",
|
|
85
|
+
" ",
|
|
86
|
+
X.totalEntities.toLocaleString(),
|
|
87
|
+
" entities processed"
|
|
88
|
+
]
|
|
89
|
+
})]
|
|
90
|
+
}),
|
|
91
|
+
$ && X.errorMessage && /* @__PURE__ */ j("div", {
|
|
92
|
+
className: "border-2 border-border-default rounded-xl bg-status-error-bg-subtle p-6 flex items-start gap-4",
|
|
93
|
+
children: [/* @__PURE__ */ A(g, {
|
|
94
|
+
size: 24,
|
|
95
|
+
className: "text-status-error-text flex-shrink-0 mt-0.5"
|
|
96
|
+
}), /* @__PURE__ */ j("div", { children: [/* @__PURE__ */ A("h3", {
|
|
97
|
+
className: "font-semibold text-status-error-text mb-1",
|
|
98
|
+
children: "Export Failed"
|
|
99
|
+
}), /* @__PURE__ */ A("p", {
|
|
100
|
+
className: "text-sm text-status-error-text",
|
|
101
|
+
children: X.errorMessage
|
|
102
|
+
})] })]
|
|
103
|
+
}),
|
|
104
|
+
/* @__PURE__ */ A("div", {
|
|
105
|
+
className: "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4",
|
|
106
|
+
children: [
|
|
107
|
+
{
|
|
108
|
+
icon: /* @__PURE__ */ A(S, { size: 18 }),
|
|
109
|
+
label: "Format",
|
|
110
|
+
value: c(X.format)
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
icon: /* @__PURE__ */ A(C, { size: 18 }),
|
|
114
|
+
label: "Archive",
|
|
115
|
+
value: s(X.archiveFormat)
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
icon: /* @__PURE__ */ A(b, { size: 18 }),
|
|
119
|
+
label: "Total Size",
|
|
120
|
+
value: X.totalSizeBytes == null ? "-" : M(X.totalSizeBytes)
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
icon: /* @__PURE__ */ A(y, { size: 18 }),
|
|
124
|
+
label: "Created",
|
|
125
|
+
value: new Date(X.createdAt).toLocaleDateString()
|
|
126
|
+
}
|
|
127
|
+
].map((e) => /* @__PURE__ */ j("div", {
|
|
128
|
+
className: "border-2 border-border/50 rounded-xl p-4 bg-gradient-to-br from-card/50 to-background",
|
|
129
|
+
children: [/* @__PURE__ */ j("div", {
|
|
130
|
+
className: "flex items-center gap-2 text-muted-foreground mb-1",
|
|
131
|
+
children: [e.icon, /* @__PURE__ */ A("span", {
|
|
132
|
+
className: "text-xs font-medium",
|
|
133
|
+
children: e.label
|
|
134
|
+
})]
|
|
135
|
+
}), /* @__PURE__ */ A("p", {
|
|
136
|
+
className: "font-bold text-lg",
|
|
137
|
+
children: e.value
|
|
138
|
+
})]
|
|
139
|
+
}, e.label))
|
|
140
|
+
}),
|
|
141
|
+
X.parts.length > 0 && /* @__PURE__ */ A(f, {
|
|
142
|
+
title: "Export Parts",
|
|
143
|
+
description: `${X.parts.length} file(s) generated`,
|
|
144
|
+
children: /* @__PURE__ */ A("div", {
|
|
145
|
+
className: "space-y-2",
|
|
146
|
+
children: X.parts.map((e) => /* @__PURE__ */ j("div", {
|
|
147
|
+
className: o("border-2 border-border/50 rounded-xl p-4 flex flex-col sm:flex-row sm:items-center sm:justify-between gap-3", "hover:border-primary/30 transition-all duration-200"),
|
|
148
|
+
children: [/* @__PURE__ */ j("div", {
|
|
149
|
+
className: "flex items-center gap-3 min-w-0",
|
|
150
|
+
children: [/* @__PURE__ */ A(x, {
|
|
151
|
+
size: 20,
|
|
152
|
+
className: "text-primary flex-shrink-0"
|
|
153
|
+
}), /* @__PURE__ */ j("div", {
|
|
154
|
+
className: "min-w-0",
|
|
155
|
+
children: [/* @__PURE__ */ A("p", {
|
|
156
|
+
className: "font-medium truncate",
|
|
157
|
+
children: e.fileName
|
|
158
|
+
}), /* @__PURE__ */ j("p", {
|
|
159
|
+
className: "text-sm text-muted-foreground",
|
|
160
|
+
children: [
|
|
161
|
+
e.entityTypes.join(", "),
|
|
162
|
+
" ·",
|
|
163
|
+
" ",
|
|
164
|
+
M(e.sizeBytes),
|
|
165
|
+
e.downloadExpiresAt && ` · expires ${new Date(e.downloadExpiresAt).toLocaleDateString()}`
|
|
166
|
+
]
|
|
167
|
+
})]
|
|
168
|
+
})]
|
|
169
|
+
}), /* @__PURE__ */ A("div", {
|
|
170
|
+
className: "flex items-center gap-2 flex-shrink-0",
|
|
171
|
+
children: e.downloadUrl ? /* @__PURE__ */ j("a", {
|
|
172
|
+
href: e.downloadUrl,
|
|
173
|
+
className: "inline-flex items-center gap-2 px-3 py-1.5 bg-primary text-primary-foreground rounded-lg hover:bg-primary/90 transition-colors text-sm font-medium",
|
|
174
|
+
children: [/* @__PURE__ */ A(b, { size: 14 }), "Download"]
|
|
175
|
+
}) : /* @__PURE__ */ j("span", {
|
|
176
|
+
className: "inline-flex items-center gap-1.5 text-sm text-muted-foreground",
|
|
177
|
+
children: [/* @__PURE__ */ A(y, { size: 14 }), "Pending"]
|
|
178
|
+
})
|
|
179
|
+
})]
|
|
180
|
+
}, e.id))
|
|
181
|
+
})
|
|
182
|
+
}),
|
|
183
|
+
Q && X.parts.length === 0 && /* @__PURE__ */ j("div", {
|
|
184
|
+
className: "border-2 border-border-default rounded-xl bg-status-success-bg-subtle p-6 text-center",
|
|
185
|
+
children: [
|
|
186
|
+
/* @__PURE__ */ A(v, {
|
|
187
|
+
size: 48,
|
|
188
|
+
className: "text-status-success-text mx-auto mb-3"
|
|
189
|
+
}),
|
|
190
|
+
/* @__PURE__ */ A("h3", {
|
|
191
|
+
className: "text-lg font-bold text-status-success-text mb-1",
|
|
192
|
+
children: "Export Complete"
|
|
193
|
+
}),
|
|
194
|
+
/* @__PURE__ */ A("p", {
|
|
195
|
+
className: "text-sm text-status-success-text",
|
|
196
|
+
children: "Your export has completed but no download parts are available yet."
|
|
197
|
+
})
|
|
198
|
+
]
|
|
199
|
+
}),
|
|
200
|
+
/* @__PURE__ */ j("div", {
|
|
201
|
+
className: "flex flex-col sm:flex-row gap-3 pt-2",
|
|
202
|
+
children: [
|
|
203
|
+
Z && /* @__PURE__ */ j("button", {
|
|
204
|
+
onClick: async () => {
|
|
205
|
+
P && U("cancel");
|
|
206
|
+
},
|
|
207
|
+
disabled: G,
|
|
208
|
+
className: "inline-flex items-center justify-center gap-2 px-6 py-3 border-2 border-status-warning-bg/50 text-status-warning-text rounded-lg hover:bg-status-warning-bg-subtle transition-all duration-200 font-medium disabled:opacity-50",
|
|
209
|
+
children: [G ? /* @__PURE__ */ A(w, {
|
|
210
|
+
size: 18,
|
|
211
|
+
className: "animate-spin"
|
|
212
|
+
}) : /* @__PURE__ */ A(D, { size: 18 }), "Cancel Export"]
|
|
213
|
+
}),
|
|
214
|
+
ee && /* @__PURE__ */ j("button", {
|
|
215
|
+
onClick: async () => {
|
|
216
|
+
if (!P) return;
|
|
217
|
+
let e = await J(P);
|
|
218
|
+
e?.id && I?.(N(F, e.id));
|
|
219
|
+
},
|
|
220
|
+
disabled: Y,
|
|
221
|
+
className: "inline-flex items-center justify-center gap-2 px-6 py-3 border-2 border-primary/50 text-primary rounded-lg hover:bg-primary/5 transition-all duration-200 font-medium disabled:opacity-50",
|
|
222
|
+
children: [Y ? /* @__PURE__ */ A(w, {
|
|
223
|
+
size: 18,
|
|
224
|
+
className: "animate-spin"
|
|
225
|
+
}) : /* @__PURE__ */ A(T, { size: 18 }), "Retry Export"]
|
|
226
|
+
}),
|
|
227
|
+
!Z && /* @__PURE__ */ j("button", {
|
|
228
|
+
onClick: async () => {
|
|
229
|
+
P && (p("medium"), U("delete"));
|
|
230
|
+
},
|
|
231
|
+
disabled: q,
|
|
232
|
+
className: "inline-flex items-center justify-center gap-2 px-6 py-3 border-2 border-status-error-bg/50 text-status-error-text rounded-lg hover:bg-status-error-bg-subtle transition-all duration-200 font-medium disabled:opacity-50",
|
|
233
|
+
children: [q ? /* @__PURE__ */ A(w, {
|
|
234
|
+
size: 18,
|
|
235
|
+
className: "animate-spin"
|
|
236
|
+
}) : /* @__PURE__ */ A(E, { size: 18 }), "Delete Export"]
|
|
237
|
+
})
|
|
238
|
+
]
|
|
239
|
+
}),
|
|
240
|
+
H && /* @__PURE__ */ A("div", {
|
|
241
|
+
role: "dialog",
|
|
242
|
+
"aria-modal": "true",
|
|
243
|
+
"aria-labelledby": "export-confirm-title",
|
|
244
|
+
className: "fixed inset-0 z-50 flex items-center justify-center bg-background/80 backdrop-blur-sm p-4",
|
|
245
|
+
children: /* @__PURE__ */ j("div", {
|
|
246
|
+
className: "w-full max-w-md rounded-xl border-2 border-border bg-card p-6 shadow-xl",
|
|
247
|
+
children: [
|
|
248
|
+
/* @__PURE__ */ A("h2", {
|
|
249
|
+
id: "export-confirm-title",
|
|
250
|
+
className: "text-lg font-bold",
|
|
251
|
+
children: H === "cancel" ? "Cancel export?" : "Delete export?"
|
|
252
|
+
}),
|
|
253
|
+
/* @__PURE__ */ A("p", {
|
|
254
|
+
className: "mt-2 text-sm text-muted-foreground",
|
|
255
|
+
children: H === "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."
|
|
256
|
+
}),
|
|
257
|
+
/* @__PURE__ */ j("div", {
|
|
258
|
+
className: "mt-6 flex flex-col-reverse sm:flex-row sm:justify-end gap-3",
|
|
259
|
+
children: [/* @__PURE__ */ A("button", {
|
|
260
|
+
type: "button",
|
|
261
|
+
onClick: () => U(null),
|
|
262
|
+
className: "px-4 py-2 rounded-lg border-2 border-border hover:bg-accent transition-colors font-medium",
|
|
263
|
+
children: "Keep Export"
|
|
264
|
+
}), /* @__PURE__ */ j("button", {
|
|
265
|
+
type: "button",
|
|
266
|
+
onClick: async () => {
|
|
267
|
+
if (!(!P || !H)) {
|
|
268
|
+
try {
|
|
269
|
+
H === "cancel" ? await W(P) : (await K(P), I?.(F)), m("success");
|
|
270
|
+
} catch {
|
|
271
|
+
m("error");
|
|
272
|
+
}
|
|
273
|
+
U(null);
|
|
274
|
+
}
|
|
275
|
+
},
|
|
276
|
+
disabled: G || q,
|
|
277
|
+
className: "inline-flex items-center justify-center gap-2 px-4 py-2 rounded-lg bg-destructive text-destructive-foreground hover:bg-destructive/90 transition-colors font-medium disabled:opacity-50",
|
|
278
|
+
children: [G || q ? /* @__PURE__ */ A(w, {
|
|
279
|
+
size: 16,
|
|
280
|
+
className: "animate-spin"
|
|
281
|
+
}) : null, H === "cancel" ? "Cancel Export" : "Delete Export"]
|
|
282
|
+
})]
|
|
283
|
+
})
|
|
284
|
+
]
|
|
285
|
+
})
|
|
286
|
+
})
|
|
287
|
+
]
|
|
288
|
+
}) : /* @__PURE__ */ j(d, {
|
|
289
|
+
showHeader: !1,
|
|
290
|
+
children: [/* @__PURE__ */ j("div", {
|
|
291
|
+
className: "flex items-center gap-3 mb-6",
|
|
292
|
+
children: [/* @__PURE__ */ A("button", {
|
|
293
|
+
onClick: R,
|
|
294
|
+
className: "p-2.5 hover:bg-accent rounded-lg transition-all duration-200",
|
|
295
|
+
children: /* @__PURE__ */ A(_, { size: 20 })
|
|
296
|
+
}), /* @__PURE__ */ A("h1", {
|
|
297
|
+
className: "text-xl font-bold",
|
|
298
|
+
children: "Export Not Found"
|
|
299
|
+
})]
|
|
300
|
+
}), /* @__PURE__ */ j("div", {
|
|
301
|
+
className: "border-2 border-border-default rounded-xl bg-status-error-bg-subtle p-12 text-center",
|
|
302
|
+
children: [
|
|
303
|
+
/* @__PURE__ */ A(g, {
|
|
304
|
+
size: 48,
|
|
305
|
+
className: "text-status-error-text mx-auto mb-4"
|
|
306
|
+
}),
|
|
307
|
+
/* @__PURE__ */ A("h3", {
|
|
308
|
+
className: "text-lg font-bold text-status-error-text mb-2",
|
|
309
|
+
children: "Export Not Found"
|
|
310
|
+
}),
|
|
311
|
+
/* @__PURE__ */ A("p", {
|
|
312
|
+
className: "text-status-error-text mb-6",
|
|
313
|
+
children: "The export job you are looking for does not exist or has been deleted."
|
|
314
|
+
}),
|
|
315
|
+
/* @__PURE__ */ j("button", {
|
|
316
|
+
onClick: R,
|
|
317
|
+
className: "inline-flex items-center gap-2 px-6 py-3 bg-primary text-primary-foreground rounded-lg hover:bg-primary/90 transition-colors font-medium",
|
|
318
|
+
children: [/* @__PURE__ */ A(_, { size: 18 }), "Back to Dashboard"]
|
|
319
|
+
})
|
|
320
|
+
]
|
|
321
|
+
})]
|
|
322
|
+
});
|
|
323
|
+
}
|
|
324
|
+
//#endregion
|
|
325
|
+
export { P as ExportDetailPage };
|
|
326
|
+
|
|
327
|
+
//# sourceMappingURL=ExportDetailPage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ExportDetailPage.js","names":[],"sources":["../../../src/export/pages/ExportDetailPage.tsx"],"sourcesContent":["import { useState } from \"react\";\nimport { useParams, useNavigate } from \"react-router-dom\";\nimport {\n ArrowLeft,\n Download,\n XCircle,\n Trash2,\n RotateCcw,\n Loader2,\n FileDown,\n Clock,\n AlertCircle,\n CheckCircle2,\n HardDrive,\n FileText,\n} from \"lucide-react\";\nimport { useExport } from \"../providers/ExportProvider\";\nimport {\n useExportJob,\n useExportJobProgress,\n useCancelExportJob,\n useDeleteExportJob,\n useRetryExportJob,\n} from \"../hooks/useExportQueries\";\nimport { ExportStatusBadge } from \"../components/ExportStatusBadge\";\nimport { ExportProgressBar } from \"../components/ExportProgressBar\";\nimport { PageLayout, PageSection } from \"../components/PageLayout\";\nimport {\n getFormatDisplayName,\n getArchiveFormatDisplayName,\n} from \"../constants/enums\";\nimport { cn } from \"../utils/cn\";\nimport { nativeImpact, nativeNotify } from \"../../utils/nativeBridge\";\n\n/**\n * Format bytes to human-readable size\n */\nfunction formatBytes(bytes: number): string {\n if (bytes === 0) return \"0 B\";\n const k = 1024;\n const sizes = [\"B\", \"KB\", \"MB\", \"GB\", \"TB\"];\n const i = Math.floor(Math.log(bytes) / Math.log(k));\n return `${parseFloat((bytes / Math.pow(k, i)).toFixed(2))} ${sizes[i]}`;\n}\n\n/**\n * Helper to join paths correctly\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 Detail Page\n * Single export job detail view with parts, progress, download links.\n * Uses GraphQL subscriptions for live progress updates when a job is active.\n */\nexport function ExportDetailPage() {\n const { jobId } = useParams<{ jobId: string }>();\n const { basePath = \"/\", navigate } = useExport();\n const routerNavigate = useNavigate();\n\n const handleBack = () => {\n if (window.history.length > 1) {\n routerNavigate(-1);\n } else {\n navigate?.(basePath);\n }\n };\n\n const { data: job, isLoading } = useExportJob(jobId);\n const { data: progressJob } = useExportJobProgress(jobId);\n const [pendingAction, setPendingAction] = useState<\n \"cancel\" | \"delete\" | null\n >(null);\n\n const { cancelJob, isPending: cancelling } = useCancelExportJob();\n const { deleteJob, isPending: deleting } = useDeleteExportJob();\n const { retryJob, isPending: retrying } = useRetryExportJob();\n\n const liveJob = progressJob ?? job ?? null;\n\n // Jobs in CREATED/QUEUED/RUNNING can still be cancelled\n const isCancellable =\n liveJob?.status === \"CREATED\" ||\n liveJob?.status === \"QUEUED\" ||\n liveJob?.status === \"RUNNING\";\n const isCompleted = liveJob?.status === \"COMPLETED\";\n const isFailed = liveJob?.status === \"FAILED\";\n const isRetryable =\n liveJob?.status === \"FAILED\" ||\n liveJob?.status === \"CANCELLED\" ||\n liveJob?.status === \"EXPIRED\";\n\n const handleCancel = async () => {\n if (!jobId) return;\n setPendingAction(\"cancel\");\n };\n\n const handleDelete = async () => {\n if (!jobId) return;\n nativeImpact(\"medium\");\n setPendingAction(\"delete\");\n };\n\n const confirmPendingAction = async () => {\n if (!jobId || !pendingAction) return;\n try {\n if (pendingAction === \"cancel\") {\n await cancelJob(jobId);\n } else {\n await deleteJob(jobId);\n navigate?.(basePath);\n }\n nativeNotify(\"success\");\n } catch {\n nativeNotify(\"error\");\n }\n setPendingAction(null);\n };\n\n const handleRetry = async () => {\n if (!jobId) return;\n const newJob = await retryJob(jobId);\n // Navigate to the new job created by retry\n if (newJob?.id) {\n navigate?.(joinPath(basePath, newJob.id));\n }\n };\n\n // Loading\n if (isLoading) {\n return (\n <div className=\"flex flex-col items-center justify-center py-20\">\n <Loader2 size={48} className=\"animate-spin text-primary\" />\n <span className=\"mt-6 text-sm font-medium text-muted-foreground\">\n Loading export details...\n </span>\n </div>\n );\n }\n\n // Not found\n if (!liveJob) {\n return (\n <PageLayout showHeader={false}>\n <div className=\"flex items-center gap-3 mb-6\">\n <button\n onClick={handleBack}\n className=\"p-2.5 hover:bg-accent rounded-lg transition-all duration-200\"\n >\n <ArrowLeft size={20} />\n </button>\n <h1 className=\"text-xl font-bold\">Export Not Found</h1>\n </div>\n <div className=\"border-2 border-border-default rounded-xl bg-status-error-bg-subtle p-12 text-center\">\n <AlertCircle\n size={48}\n className=\"text-status-error-text mx-auto mb-4\"\n />\n <h3 className=\"text-lg font-bold text-status-error-text mb-2\">\n Export Not Found\n </h3>\n <p className=\"text-status-error-text mb-6\">\n The export job you are looking for does not exist or has been\n deleted.\n </p>\n <button\n onClick={handleBack}\n className=\"inline-flex items-center gap-2 px-6 py-3 bg-primary text-primary-foreground rounded-lg hover:bg-primary/90 transition-colors font-medium\"\n >\n <ArrowLeft size={18} />\n Back to Dashboard\n </button>\n </div>\n </PageLayout>\n );\n }\n\n return (\n <PageLayout showHeader={false}>\n {/* Header */}\n <div className=\"relative overflow-hidden rounded-xl bg-gradient-to-br from-primary/5 via-primary/3 to-background border border-border/50 p-6 shadow-sm\">\n <div className=\"relative z-10 flex items-center gap-4\">\n <button\n onClick={handleBack}\n className=\"p-2.5 hover:bg-accent rounded-lg transition-all duration-200\"\n >\n <ArrowLeft size={20} />\n </button>\n <div className=\"flex items-center gap-3 flex-1\">\n <div className=\"p-2.5 rounded-lg bg-primary/10\">\n <Download size={24} className=\"text-primary\" />\n </div>\n <div className=\"flex-1 min-w-0\">\n <h1 className=\"text-xl sm:text-2xl font-bold truncate\">\n {liveJob.name}\n </h1>\n <p className=\"text-sm text-muted-foreground mt-1\">\n {liveJob.entityTypes.join(\", \")}\n </p>\n </div>\n <ExportStatusBadge status={liveJob.status} />\n </div>\n </div>\n </div>\n\n {/* Progress (for active jobs) */}\n {(liveJob.status === \"RUNNING\" || liveJob.status === \"QUEUED\") && (\n <div className=\"border-2 border-border-default rounded-xl bg-status-info-bg-subtle p-6\">\n <ExportProgressBar progress={liveJob.progress} size=\"lg\" />\n {liveJob.processedEntities != null &&\n liveJob.totalEntities != null && (\n <p className=\"text-sm text-muted-foreground mt-2\">\n {liveJob.processedEntities.toLocaleString()} /{\" \"}\n {liveJob.totalEntities.toLocaleString()} entities processed\n </p>\n )}\n </div>\n )}\n\n {/* Error (for failed jobs) */}\n {isFailed && liveJob.errorMessage && (\n <div className=\"border-2 border-border-default rounded-xl bg-status-error-bg-subtle p-6 flex items-start gap-4\">\n <AlertCircle\n size={24}\n className=\"text-status-error-text flex-shrink-0 mt-0.5\"\n />\n <div>\n <h3 className=\"font-semibold text-status-error-text mb-1\">\n Export Failed\n </h3>\n <p className=\"text-sm text-status-error-text\">\n {liveJob.errorMessage}\n </p>\n </div>\n </div>\n )}\n\n {/* Info Grid */}\n <div className=\"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4\">\n {[\n {\n icon: <FileText size={18} />,\n label: \"Format\",\n value: getFormatDisplayName(liveJob.format),\n },\n {\n icon: <HardDrive size={18} />,\n label: \"Archive\",\n value: getArchiveFormatDisplayName(liveJob.archiveFormat),\n },\n {\n icon: <Download size={18} />,\n label: \"Total Size\",\n value:\n liveJob.totalSizeBytes != null\n ? formatBytes(liveJob.totalSizeBytes)\n : \"-\",\n },\n {\n icon: <Clock size={18} />,\n label: \"Created\",\n value: new Date(liveJob.createdAt).toLocaleDateString(),\n },\n ].map((item) => (\n <div\n key={item.label}\n className=\"border-2 border-border/50 rounded-xl p-4 bg-gradient-to-br from-card/50 to-background\"\n >\n <div className=\"flex items-center gap-2 text-muted-foreground mb-1\">\n {item.icon}\n <span className=\"text-xs font-medium\">{item.label}</span>\n </div>\n <p className=\"font-bold text-lg\">{item.value}</p>\n </div>\n ))}\n </div>\n\n {/* Parts */}\n {liveJob.parts.length > 0 && (\n <PageSection\n title=\"Export Parts\"\n description={`${liveJob.parts.length} file(s) generated`}\n >\n <div className=\"space-y-2\">\n {liveJob.parts.map((part) => (\n <div\n key={part.id}\n className={cn(\n \"border-2 border-border/50 rounded-xl p-4 flex flex-col sm:flex-row sm:items-center sm:justify-between gap-3\",\n \"hover:border-primary/30 transition-all duration-200\",\n )}\n >\n <div className=\"flex items-center gap-3 min-w-0\">\n <FileDown size={20} className=\"text-primary flex-shrink-0\" />\n <div className=\"min-w-0\">\n <p className=\"font-medium truncate\">{part.fileName}</p>\n <p className=\"text-sm text-muted-foreground\">\n {part.entityTypes.join(\", \")} ·{\" \"}\n {formatBytes(part.sizeBytes)}\n {part.downloadExpiresAt &&\n ` · expires ${new Date(part.downloadExpiresAt).toLocaleDateString()}`}\n </p>\n </div>\n </div>\n <div className=\"flex items-center gap-2 flex-shrink-0\">\n {part.downloadUrl ? (\n <a\n href={part.downloadUrl}\n className=\"inline-flex items-center gap-2 px-3 py-1.5 bg-primary text-primary-foreground rounded-lg hover:bg-primary/90 transition-colors text-sm font-medium\"\n >\n <Download size={14} />\n Download\n </a>\n ) : (\n <span className=\"inline-flex items-center gap-1.5 text-sm text-muted-foreground\">\n <Clock size={14} />\n Pending\n </span>\n )}\n </div>\n </div>\n ))}\n </div>\n </PageSection>\n )}\n\n {/* Completed message when no parts yet */}\n {isCompleted && liveJob.parts.length === 0 && (\n <div className=\"border-2 border-border-default rounded-xl bg-status-success-bg-subtle p-6 text-center\">\n <CheckCircle2\n size={48}\n className=\"text-status-success-text mx-auto mb-3\"\n />\n <h3 className=\"text-lg font-bold text-status-success-text mb-1\">\n Export Complete\n </h3>\n <p className=\"text-sm text-status-success-text\">\n Your export has completed but no download parts are available yet.\n </p>\n </div>\n )}\n\n {/* Actions */}\n <div className=\"flex flex-col sm:flex-row gap-3 pt-2\">\n {isCancellable && (\n <button\n onClick={handleCancel}\n disabled={cancelling}\n className=\"inline-flex items-center justify-center gap-2 px-6 py-3 border-2 border-status-warning-bg/50 text-status-warning-text rounded-lg hover:bg-status-warning-bg-subtle transition-all duration-200 font-medium disabled:opacity-50\"\n >\n {cancelling ? (\n <Loader2 size={18} className=\"animate-spin\" />\n ) : (\n <XCircle size={18} />\n )}\n Cancel Export\n </button>\n )}\n {isRetryable && (\n <button\n onClick={handleRetry}\n disabled={retrying}\n className=\"inline-flex items-center justify-center gap-2 px-6 py-3 border-2 border-primary/50 text-primary rounded-lg hover:bg-primary/5 transition-all duration-200 font-medium disabled:opacity-50\"\n >\n {retrying ? (\n <Loader2 size={18} className=\"animate-spin\" />\n ) : (\n <RotateCcw size={18} />\n )}\n Retry Export\n </button>\n )}\n {!isCancellable && (\n <button\n onClick={handleDelete}\n disabled={deleting}\n className=\"inline-flex items-center justify-center gap-2 px-6 py-3 border-2 border-status-error-bg/50 text-status-error-text rounded-lg hover:bg-status-error-bg-subtle transition-all duration-200 font-medium disabled:opacity-50\"\n >\n {deleting ? (\n <Loader2 size={18} className=\"animate-spin\" />\n ) : (\n <Trash2 size={18} />\n )}\n Delete Export\n </button>\n )}\n </div>\n\n {pendingAction && (\n <div\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby=\"export-confirm-title\"\n className=\"fixed inset-0 z-50 flex items-center justify-center bg-background/80 backdrop-blur-sm p-4\"\n >\n <div className=\"w-full max-w-md rounded-xl border-2 border-border bg-card p-6 shadow-xl\">\n <h2 id=\"export-confirm-title\" className=\"text-lg font-bold\">\n {pendingAction === \"cancel\" ? \"Cancel export?\" : \"Delete export?\"}\n </h2>\n <p className=\"mt-2 text-sm text-muted-foreground\">\n {pendingAction === \"cancel\"\n ? \"This stops the running export job. You can retry it later if needed.\"\n : \"This removes the export job from history. This action cannot be undone.\"}\n </p>\n <div className=\"mt-6 flex flex-col-reverse sm:flex-row sm:justify-end gap-3\">\n <button\n type=\"button\"\n onClick={() => setPendingAction(null)}\n className=\"px-4 py-2 rounded-lg border-2 border-border hover:bg-accent transition-colors font-medium\"\n >\n Keep Export\n </button>\n <button\n type=\"button\"\n onClick={confirmPendingAction}\n disabled={cancelling || deleting}\n className=\"inline-flex items-center justify-center gap-2 px-4 py-2 rounded-lg bg-destructive text-destructive-foreground hover:bg-destructive/90 transition-colors font-medium disabled:opacity-50\"\n >\n {cancelling || deleting ? (\n <Loader2 size={16} className=\"animate-spin\" />\n ) : null}\n {pendingAction === \"cancel\" ? \"Cancel Export\" : \"Delete Export\"}\n </button>\n </div>\n </div>\n </div>\n )}\n </PageLayout>\n );\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ExportHistoryPage.d.ts","sourceRoot":"","sources":["../../../src/export/pages/ExportHistoryPage.tsx"],"names":[],"mappings":"AAqCA;;;GAGG;AACH,wBAAgB,iBAAiB,4CAsZhC"}
|