@burdenoff/microfe-export 2026.513.2 → 2026.514.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/ExportRoutes.d.ts.map +1 -1
- package/dist/export/ExportRoutes.js +85 -50
- package/dist/export/ExportRoutes.js.map +1 -1
- package/dist/export/pages/CreateExportPage.d.ts.map +1 -1
- package/dist/export/pages/CreateExportPage.js +223 -210
- package/dist/export/pages/CreateExportPage.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ExportRoutes.d.ts","sourceRoot":"","sources":["../../src/export/ExportRoutes.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ExportRoutes.d.ts","sourceRoot":"","sources":["../../src/export/ExportRoutes.tsx"],"names":[],"mappings":"AA8IA;;;;;;;;;;;GAWG;AACH,wBAAgB,YAAY,4CAoC3B"}
|
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
import { ExportLandingPage as e } from "./pages/ExportLandingPage.js";
|
|
2
2
|
import { Component as t, Suspense as n, lazy as r } from "react";
|
|
3
3
|
import { AlertTriangle as i, Loader2 as a, RefreshCw as o } from "lucide-react";
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
4
|
+
import { FeatureGate as s } from "@burdenoff/fe-libs/shared/feature-flags";
|
|
5
|
+
import { Navigate as c, Route as l, Routes as u } from "react-router-dom";
|
|
6
|
+
import { jsx as d, jsxs as f } from "react/jsx-runtime";
|
|
6
7
|
//#region src/export/ExportRoutes.tsx
|
|
7
|
-
var
|
|
8
|
-
function
|
|
9
|
-
return /* @__PURE__ */
|
|
8
|
+
var p = r(() => import("./pages/CreateExportPage.js").then((e) => ({ default: e.CreateExportPage }))), m = r(() => import("./pages/ExportHistoryPage.js").then((e) => ({ default: e.ExportHistoryPage }))), h = r(() => import("./pages/ExportDetailPage.js").then((e) => ({ default: e.ExportDetailPage }))), g = r(() => import("./pages/ExportTemplatesPage.js").then((e) => ({ default: e.ExportTemplatesPage }))), _ = r(() => import("./pages/TemplateDetailPage.js").then((e) => ({ default: e.TemplateDetailPage })));
|
|
9
|
+
function v() {
|
|
10
|
+
return /* @__PURE__ */ d("div", {
|
|
10
11
|
className: "flex items-center justify-center min-h-[400px]",
|
|
11
|
-
children: /* @__PURE__ */
|
|
12
|
+
children: /* @__PURE__ */ d(a, { className: "h-8 w-8 animate-spin text-primary" })
|
|
12
13
|
});
|
|
13
14
|
}
|
|
14
|
-
var
|
|
15
|
+
var y = class extends t {
|
|
15
16
|
constructor(e) {
|
|
16
17
|
super(e), this.state = {
|
|
17
18
|
hasError: !1,
|
|
@@ -34,71 +35,105 @@ var v = class extends t {
|
|
|
34
35
|
});
|
|
35
36
|
};
|
|
36
37
|
render() {
|
|
37
|
-
return this.state.hasError ? /* @__PURE__ */
|
|
38
|
+
return this.state.hasError ? /* @__PURE__ */ f("div", {
|
|
38
39
|
className: "flex flex-col items-center justify-center min-h-[400px] gap-4 text-center p-6",
|
|
39
40
|
children: [
|
|
40
|
-
/* @__PURE__ */
|
|
41
|
+
/* @__PURE__ */ d("div", {
|
|
41
42
|
className: "p-3 rounded-full bg-destructive/10",
|
|
42
|
-
children: /* @__PURE__ */
|
|
43
|
+
children: /* @__PURE__ */ d(i, { className: "h-8 w-8 text-destructive" })
|
|
43
44
|
}),
|
|
44
|
-
/* @__PURE__ */
|
|
45
|
+
/* @__PURE__ */ f("div", {
|
|
45
46
|
className: "space-y-2",
|
|
46
|
-
children: [/* @__PURE__ */
|
|
47
|
+
children: [/* @__PURE__ */ d("h3", {
|
|
47
48
|
className: "text-lg font-semibold text-foreground",
|
|
48
49
|
children: "Failed to load page"
|
|
49
|
-
}), /* @__PURE__ */
|
|
50
|
+
}), /* @__PURE__ */ d("p", {
|
|
50
51
|
className: "text-sm text-muted-foreground max-w-md",
|
|
51
52
|
children: this.state.error?.message || "The page chunk could not be loaded. This may be due to a network issue."
|
|
52
53
|
})]
|
|
53
54
|
}),
|
|
54
|
-
/* @__PURE__ */
|
|
55
|
+
/* @__PURE__ */ f("button", {
|
|
55
56
|
onClick: this.handleRetry,
|
|
56
57
|
className: "inline-flex items-center gap-2 px-4 py-2 text-sm font-medium rounded-md bg-primary text-primary-foreground hover:bg-primary/90 transition-colors",
|
|
57
|
-
children: [/* @__PURE__ */
|
|
58
|
+
children: [/* @__PURE__ */ d(o, { className: "h-4 w-4" }), "Try Again"]
|
|
58
59
|
})
|
|
59
60
|
]
|
|
60
61
|
}) : this.props.children;
|
|
61
62
|
}
|
|
62
63
|
};
|
|
63
|
-
function
|
|
64
|
-
return /* @__PURE__ */
|
|
65
|
-
|
|
66
|
-
children: /* @__PURE__ */ d(
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
}),
|
|
79
|
-
/* @__PURE__ */ u(c, {
|
|
80
|
-
path: ":jobId",
|
|
81
|
-
element: /* @__PURE__ */ u(m, {})
|
|
82
|
-
}),
|
|
83
|
-
/* @__PURE__ */ u(c, {
|
|
84
|
-
path: "templates",
|
|
85
|
-
element: /* @__PURE__ */ u(h, {})
|
|
86
|
-
}),
|
|
87
|
-
/* @__PURE__ */ u(c, {
|
|
88
|
-
path: "templates/:templateId",
|
|
89
|
-
element: /* @__PURE__ */ u(g, {})
|
|
90
|
-
}),
|
|
91
|
-
/* @__PURE__ */ u(c, {
|
|
92
|
-
path: "*",
|
|
93
|
-
element: /* @__PURE__ */ u(s, {
|
|
94
|
-
to: "",
|
|
95
|
-
replace: !0
|
|
64
|
+
function b() {
|
|
65
|
+
return /* @__PURE__ */ f("div", {
|
|
66
|
+
className: "flex flex-col items-center justify-center min-h-[400px] gap-4 text-center p-6",
|
|
67
|
+
children: [/* @__PURE__ */ d("div", {
|
|
68
|
+
className: "p-3 rounded-full bg-muted",
|
|
69
|
+
children: /* @__PURE__ */ d("svg", {
|
|
70
|
+
className: "h-8 w-8 text-muted-foreground",
|
|
71
|
+
fill: "none",
|
|
72
|
+
viewBox: "0 0 24 24",
|
|
73
|
+
stroke: "currentColor",
|
|
74
|
+
strokeWidth: 1.5,
|
|
75
|
+
children: /* @__PURE__ */ d("path", {
|
|
76
|
+
strokeLinecap: "round",
|
|
77
|
+
strokeLinejoin: "round",
|
|
78
|
+
d: "M3 16.5v2.25A2.25 2.25 0 005.25 21h13.5A2.25 2.25 0 0021 18.75V16.5M16.5 12L12 16.5m0 0L7.5 12m4.5 4.5V3"
|
|
96
79
|
})
|
|
97
80
|
})
|
|
98
|
-
|
|
81
|
+
}), /* @__PURE__ */ f("div", {
|
|
82
|
+
className: "space-y-2",
|
|
83
|
+
children: [/* @__PURE__ */ d("h3", {
|
|
84
|
+
className: "text-lg font-semibold text-foreground",
|
|
85
|
+
children: "Data Export Unavailable"
|
|
86
|
+
}), /* @__PURE__ */ d("p", {
|
|
87
|
+
className: "text-sm text-muted-foreground max-w-md",
|
|
88
|
+
children: "The Data Export feature is currently disabled for this workspace. Contact your administrator to enable it."
|
|
89
|
+
})]
|
|
90
|
+
})]
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
function x() {
|
|
94
|
+
return /* @__PURE__ */ d(y, { children: /* @__PURE__ */ d(s, {
|
|
95
|
+
flag: "workspaces.export",
|
|
96
|
+
defaultValue: !0,
|
|
97
|
+
fallback: /* @__PURE__ */ d(b, {}),
|
|
98
|
+
children: /* @__PURE__ */ d(n, {
|
|
99
|
+
fallback: /* @__PURE__ */ d(v, {}),
|
|
100
|
+
children: /* @__PURE__ */ f(u, { children: [
|
|
101
|
+
/* @__PURE__ */ d(l, {
|
|
102
|
+
index: !0,
|
|
103
|
+
element: /* @__PURE__ */ d(e, {})
|
|
104
|
+
}),
|
|
105
|
+
/* @__PURE__ */ d(l, {
|
|
106
|
+
path: "new",
|
|
107
|
+
element: /* @__PURE__ */ d(p, {})
|
|
108
|
+
}),
|
|
109
|
+
/* @__PURE__ */ d(l, {
|
|
110
|
+
path: "history",
|
|
111
|
+
element: /* @__PURE__ */ d(m, {})
|
|
112
|
+
}),
|
|
113
|
+
/* @__PURE__ */ d(l, {
|
|
114
|
+
path: ":jobId",
|
|
115
|
+
element: /* @__PURE__ */ d(h, {})
|
|
116
|
+
}),
|
|
117
|
+
/* @__PURE__ */ d(l, {
|
|
118
|
+
path: "templates",
|
|
119
|
+
element: /* @__PURE__ */ d(g, {})
|
|
120
|
+
}),
|
|
121
|
+
/* @__PURE__ */ d(l, {
|
|
122
|
+
path: "templates/:templateId",
|
|
123
|
+
element: /* @__PURE__ */ d(_, {})
|
|
124
|
+
}),
|
|
125
|
+
/* @__PURE__ */ d(l, {
|
|
126
|
+
path: "*",
|
|
127
|
+
element: /* @__PURE__ */ d(c, {
|
|
128
|
+
to: "",
|
|
129
|
+
replace: !0
|
|
130
|
+
})
|
|
131
|
+
})
|
|
132
|
+
] })
|
|
133
|
+
})
|
|
99
134
|
}) });
|
|
100
135
|
}
|
|
101
136
|
//#endregion
|
|
102
|
-
export {
|
|
137
|
+
export { x as ExportRoutes };
|
|
103
138
|
|
|
104
139
|
//# sourceMappingURL=ExportRoutes.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ExportRoutes.js","names":[],"sources":["../../src/export/ExportRoutes.tsx"],"sourcesContent":["import {\n lazy,\n Suspense,\n Component,\n type ReactNode,\n type ErrorInfo,\n} from \"react\";\nimport { Navigate, Route, Routes } from \"react-router-dom\";\nimport { Loader2, AlertTriangle, RefreshCw } from \"lucide-react\";\n\n// Eager loaded - primary landing page\nimport { ExportLandingPage } from \"./pages/ExportLandingPage\";\n\n// Lazy loaded pages\nconst CreateExportPage = lazy(() =>\n import(\"./pages/CreateExportPage\").then((m) => ({\n default: m.CreateExportPage,\n })),\n);\nconst ExportHistoryPage = lazy(() =>\n import(\"./pages/ExportHistoryPage\").then((m) => ({\n default: m.ExportHistoryPage,\n })),\n);\nconst ExportDetailPage = lazy(() =>\n import(\"./pages/ExportDetailPage\").then((m) => ({\n default: m.ExportDetailPage,\n })),\n);\nconst ExportTemplatesPage = lazy(() =>\n import(\"./pages/ExportTemplatesPage\").then((m) => ({\n default: m.ExportTemplatesPage,\n })),\n);\nconst TemplateDetailPage = lazy(() =>\n import(\"./pages/TemplateDetailPage\").then((m) => ({\n default: m.TemplateDetailPage,\n })),\n);\n\n/**\n * Loading fallback for lazy-loaded pages\n */\nfunction PageLoader() {\n return (\n <div className=\"flex items-center justify-center min-h-[400px]\">\n <Loader2 className=\"h-8 w-8 animate-spin text-primary\" />\n </div>\n );\n}\n\n/**\n * Error boundary for lazy-loaded page chunks.\n * Catches chunk-load failures and renders a retry UI instead of an infinite spinner.\n */\nclass LazyErrorBoundary extends Component<\n { children: ReactNode },\n { hasError: boolean; error: Error | null }\n> {\n constructor(props: { children: ReactNode }) {\n super(props);\n this.state = { hasError: false, error: null };\n }\n\n static getDerivedStateFromError(error: Error) {\n return { hasError: true, error };\n }\n\n componentDidCatch(error: Error, errorInfo: ErrorInfo) {\n console.error(\"[Export] Lazy page load failed:\", error, errorInfo);\n }\n\n handleRetry = () => {\n this.setState({ hasError: false, error: null });\n };\n\n render() {\n if (this.state.hasError) {\n return (\n <div className=\"flex flex-col items-center justify-center min-h-[400px] gap-4 text-center p-6\">\n <div className=\"p-3 rounded-full bg-destructive/10\">\n <AlertTriangle className=\"h-8 w-8 text-destructive\" />\n </div>\n <div className=\"space-y-2\">\n <h3 className=\"text-lg font-semibold text-foreground\">\n Failed to load page\n </h3>\n <p className=\"text-sm text-muted-foreground max-w-md\">\n {this.state.error?.message ||\n \"The page chunk could not be loaded. This may be due to a network issue.\"}\n </p>\n </div>\n <button\n onClick={this.handleRetry}\n className=\"inline-flex items-center gap-2 px-4 py-2 text-sm font-medium rounded-md bg-primary text-primary-foreground hover:bg-primary/90 transition-colors\"\n >\n <RefreshCw className=\"h-4 w-4\" />\n Try Again\n </button>\n </div>\n );\n }\n\n return this.props.children;\n }\n}\n\n/**\n * Internal router for the Export microfrontend.\n * This component handles routing within the microfrontend using React Router v7.\n *\n * Routes (relative to basePath, e.g., /export):\n * - / → Export dashboard page\n * - /new → Create new export job\n * - /history → Export history list\n * - /:jobId → Export job detail page\n * - /templates → Export templates list\n * - /templates/:templateId → Template detail page\n */\nexport function ExportRoutes() {\n return (\n <LazyErrorBoundary>\n <Suspense fallback={<PageLoader />}>\n
|
|
1
|
+
{"version":3,"file":"ExportRoutes.js","names":[],"sources":["../../src/export/ExportRoutes.tsx"],"sourcesContent":["import {\n lazy,\n Suspense,\n Component,\n type ReactNode,\n type ErrorInfo,\n} from \"react\";\nimport { Navigate, Route, Routes } from \"react-router-dom\";\nimport { Loader2, AlertTriangle, RefreshCw } from \"lucide-react\";\nimport { FeatureGate } from \"@burdenoff/fe-libs/shared/feature-flags\";\n\n// Eager loaded - primary landing page\nimport { ExportLandingPage } from \"./pages/ExportLandingPage\";\n\n// Lazy loaded pages\nconst CreateExportPage = lazy(() =>\n import(\"./pages/CreateExportPage\").then((m) => ({\n default: m.CreateExportPage,\n })),\n);\nconst ExportHistoryPage = lazy(() =>\n import(\"./pages/ExportHistoryPage\").then((m) => ({\n default: m.ExportHistoryPage,\n })),\n);\nconst ExportDetailPage = lazy(() =>\n import(\"./pages/ExportDetailPage\").then((m) => ({\n default: m.ExportDetailPage,\n })),\n);\nconst ExportTemplatesPage = lazy(() =>\n import(\"./pages/ExportTemplatesPage\").then((m) => ({\n default: m.ExportTemplatesPage,\n })),\n);\nconst TemplateDetailPage = lazy(() =>\n import(\"./pages/TemplateDetailPage\").then((m) => ({\n default: m.TemplateDetailPage,\n })),\n);\n\n/**\n * Loading fallback for lazy-loaded pages\n */\nfunction PageLoader() {\n return (\n <div className=\"flex items-center justify-center min-h-[400px]\">\n <Loader2 className=\"h-8 w-8 animate-spin text-primary\" />\n </div>\n );\n}\n\n/**\n * Error boundary for lazy-loaded page chunks.\n * Catches chunk-load failures and renders a retry UI instead of an infinite spinner.\n */\nclass LazyErrorBoundary extends Component<\n { children: ReactNode },\n { hasError: boolean; error: Error | null }\n> {\n constructor(props: { children: ReactNode }) {\n super(props);\n this.state = { hasError: false, error: null };\n }\n\n static getDerivedStateFromError(error: Error) {\n return { hasError: true, error };\n }\n\n componentDidCatch(error: Error, errorInfo: ErrorInfo) {\n console.error(\"[Export] Lazy page load failed:\", error, errorInfo);\n }\n\n handleRetry = () => {\n this.setState({ hasError: false, error: null });\n };\n\n render() {\n if (this.state.hasError) {\n return (\n <div className=\"flex flex-col items-center justify-center min-h-[400px] gap-4 text-center p-6\">\n <div className=\"p-3 rounded-full bg-destructive/10\">\n <AlertTriangle className=\"h-8 w-8 text-destructive\" />\n </div>\n <div className=\"space-y-2\">\n <h3 className=\"text-lg font-semibold text-foreground\">\n Failed to load page\n </h3>\n <p className=\"text-sm text-muted-foreground max-w-md\">\n {this.state.error?.message ||\n \"The page chunk could not be loaded. This may be due to a network issue.\"}\n </p>\n </div>\n <button\n onClick={this.handleRetry}\n className=\"inline-flex items-center gap-2 px-4 py-2 text-sm font-medium rounded-md bg-primary text-primary-foreground hover:bg-primary/90 transition-colors\"\n >\n <RefreshCw className=\"h-4 w-4\" />\n Try Again\n </button>\n </div>\n );\n }\n\n return this.props.children;\n }\n}\n\n/**\n * Fallback shown when the Export feature flag is OFF.\n */\nfunction ExportDisabledFallback() {\n return (\n <div className=\"flex flex-col items-center justify-center min-h-[400px] gap-4 text-center p-6\">\n <div className=\"p-3 rounded-full bg-muted\">\n <svg\n className=\"h-8 w-8 text-muted-foreground\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n strokeWidth={1.5}\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n d=\"M3 16.5v2.25A2.25 2.25 0 005.25 21h13.5A2.25 2.25 0 0021 18.75V16.5M16.5 12L12 16.5m0 0L7.5 12m4.5 4.5V3\"\n />\n </svg>\n </div>\n <div className=\"space-y-2\">\n <h3 className=\"text-lg font-semibold text-foreground\">\n Data Export Unavailable\n </h3>\n <p className=\"text-sm text-muted-foreground max-w-md\">\n The Data Export feature is currently disabled for this workspace.\n Contact your administrator to enable it.\n </p>\n </div>\n </div>\n );\n}\n\n/**\n * Internal router for the Export microfrontend.\n * This component handles routing within the microfrontend using React Router v7.\n *\n * Routes (relative to basePath, e.g., /export):\n * - / → Export dashboard page\n * - /new → Create new export job\n * - /history → Export history list\n * - /:jobId → Export job detail page\n * - /templates → Export templates list\n * - /templates/:templateId → Template detail page\n */\nexport function ExportRoutes() {\n return (\n <LazyErrorBoundary>\n <FeatureGate\n flag=\"workspaces.export\"\n defaultValue={true}\n fallback={<ExportDisabledFallback />}\n >\n <Suspense fallback={<PageLoader />}>\n <Routes>\n {/* Tabbed landing - default route (eager loaded) */}\n <Route index element={<ExportLandingPage />} />\n\n {/* Create new export (lazy loaded) */}\n <Route path=\"new\" element={<CreateExportPage />} />\n\n {/* Export history (lazy loaded) */}\n <Route path=\"history\" element={<ExportHistoryPage />} />\n\n {/* Export job detail (lazy loaded) */}\n <Route path=\":jobId\" element={<ExportDetailPage />} />\n\n {/* Templates (lazy loaded) */}\n <Route path=\"templates\" element={<ExportTemplatesPage />} />\n <Route\n path=\"templates/:templateId\"\n element={<TemplateDetailPage />}\n />\n\n {/* Catch-all route - redirect to dashboard */}\n <Route path=\"*\" element={<Navigate to=\"\" replace />} />\n </Routes>\n </Suspense>\n </FeatureGate>\n </LazyErrorBoundary>\n );\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CreateExportPage.d.ts","sourceRoot":"","sources":["../../../src/export/pages/CreateExportPage.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"CreateExportPage.d.ts","sourceRoot":"","sources":["../../../src/export/pages/CreateExportPage.tsx"],"names":[],"mappings":"AAyEA,wBAAgB,gBAAgB,4CA+sB/B"}
|
|
@@ -3,219 +3,220 @@ import { useAvailableEntities as t, useCreateExportJob as n, useExportTemplates
|
|
|
3
3
|
import { cn as i } from "../utils/cn.js";
|
|
4
4
|
import { getFormatDisplayName as a } from "../constants/enums.js";
|
|
5
5
|
import { tWithFallback as o } from "../utils/i18n.js";
|
|
6
|
-
import { PageLayout as
|
|
7
|
-
import { useEffect as
|
|
8
|
-
import { ArrowLeft as
|
|
9
|
-
import { useSearchParams as
|
|
10
|
-
import { jsx as
|
|
11
|
-
import { useI18n as
|
|
6
|
+
import { PageLayout as ee } from "../components/PageLayout.js";
|
|
7
|
+
import { useEffect as s, useRef as te, useState as c } from "react";
|
|
8
|
+
import { ArrowLeft as l, ArrowRight as u, Building2 as d, CalendarRange as ne, CheckCircle2 as f, Download as p, FileJson as m, FileSpreadsheet as h, Loader2 as g, Lock as _, Package as re, User as v, Users as y } from "lucide-react";
|
|
9
|
+
import { useSearchParams as b } from "react-router-dom";
|
|
10
|
+
import { jsx as x, jsxs as S } from "react/jsx-runtime";
|
|
11
|
+
import { useI18n as C } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
|
|
12
|
+
import { usePermission as w } from "@burdenoff/fe-libs/shared/providers/shell";
|
|
12
13
|
//#region src/export/pages/CreateExportPage.tsx
|
|
13
|
-
var
|
|
14
|
-
CSV:
|
|
15
|
-
JSON:
|
|
16
|
-
},
|
|
14
|
+
var T = ["CSV", "JSON"], ie = {
|
|
15
|
+
CSV: h,
|
|
16
|
+
JSON: m
|
|
17
|
+
}, ae = [
|
|
17
18
|
{
|
|
18
19
|
value: "INDIVIDUAL",
|
|
19
20
|
label: "My Data Only",
|
|
20
21
|
description: "Export data you personally created across selected modules.",
|
|
21
|
-
Icon:
|
|
22
|
+
Icon: v
|
|
22
23
|
},
|
|
23
24
|
{
|
|
24
25
|
value: "WORKSPACE_ADMIN",
|
|
25
26
|
label: "All Workspace Data",
|
|
26
27
|
description: "Export all data in this workspace regardless of who created it. Requires workspace admin access.",
|
|
27
|
-
Icon:
|
|
28
|
+
Icon: y
|
|
28
29
|
},
|
|
29
30
|
{
|
|
30
31
|
value: "ORG_ADMIN",
|
|
31
32
|
label: "All Organization Data",
|
|
32
33
|
description: "Export data from every workspace in your organization. Requires org-admin access.",
|
|
33
|
-
Icon:
|
|
34
|
+
Icon: d
|
|
34
35
|
}
|
|
35
36
|
];
|
|
36
|
-
function
|
|
37
|
-
let { basePath:
|
|
38
|
-
|
|
39
|
-
let e =
|
|
40
|
-
if (!e || !
|
|
41
|
-
let t =
|
|
37
|
+
function E() {
|
|
38
|
+
let { basePath: d = "/", navigate: m, organizationId: h } = e(), { t: v } = C(), y = (e, t, n) => o(v, e, t, n), { createJob: E, isPending: D } = n(), { data: O } = t(), { data: k } = r(), [A] = b(), j = w("export:workspace:admin"), oe = w("export:org:admin"), [M, N] = c("entities"), [P, F] = c([]), [I, L] = c(""), [R, z] = c("CSV"), [B, V] = c("INDIVIDUAL"), [H, U] = c(A.get("templateId") ?? void 0), [W, G] = c(""), [K, se] = c(""), [q, J] = c(null), Y = te(null);
|
|
39
|
+
s(() => {
|
|
40
|
+
let e = A.get("templateId");
|
|
41
|
+
if (!e || !k?.length || Y.current === e) return;
|
|
42
|
+
let t = k.find((t) => t.id === e);
|
|
42
43
|
if (!t) return;
|
|
43
|
-
|
|
44
|
+
Y.current = e, U(t.id), F(t.entityTypes ?? []);
|
|
44
45
|
let n = t.format?.toUpperCase();
|
|
45
|
-
n &&
|
|
46
|
-
}, [
|
|
47
|
-
let
|
|
48
|
-
M === "options" ? N("entities") : M === "review" ? N("options") :
|
|
49
|
-
},
|
|
46
|
+
n && T.includes(n) && z(n), t.name && L(t.name);
|
|
47
|
+
}, [A, k]);
|
|
48
|
+
let ce = () => {
|
|
49
|
+
M === "options" ? N("entities") : M === "review" ? N("options") : m?.(d);
|
|
50
|
+
}, X = () => {
|
|
50
51
|
if (M === "entities") {
|
|
51
52
|
if (P.length === 0) {
|
|
52
|
-
|
|
53
|
+
J(y("export.create.errors.selectEntity", "Please select at least one entity type to export"));
|
|
53
54
|
return;
|
|
54
55
|
}
|
|
55
|
-
|
|
56
|
+
J(null), N("options");
|
|
56
57
|
} else if (M === "options") {
|
|
57
58
|
if (!I.trim()) {
|
|
58
|
-
|
|
59
|
+
J(y("export.create.errors.exportNameRequired", "Please provide a name for this export"));
|
|
59
60
|
return;
|
|
60
61
|
}
|
|
61
|
-
|
|
62
|
+
J(null), N("review");
|
|
62
63
|
}
|
|
63
|
-
},
|
|
64
|
+
}, le = async () => {
|
|
64
65
|
try {
|
|
65
|
-
|
|
66
|
+
J(null), await E({
|
|
66
67
|
name: I,
|
|
67
68
|
entityTypes: P,
|
|
68
69
|
format: R,
|
|
69
70
|
exportScope: B,
|
|
70
|
-
organizationId: B === "ORG_ADMIN" ?
|
|
71
|
+
organizationId: B === "ORG_ADMIN" ? h : void 0,
|
|
71
72
|
templateId: H,
|
|
72
73
|
dateRangeStart: W ? new Date(W).toISOString() : null,
|
|
73
74
|
dateRangeEnd: K ? new Date(K).toISOString() : null
|
|
74
|
-
}),
|
|
75
|
+
}), m?.(d);
|
|
75
76
|
} catch (e) {
|
|
76
|
-
|
|
77
|
+
J(e instanceof Error ? e.message : y("export.create.errors.createFailed", "Failed to create export"));
|
|
77
78
|
}
|
|
78
|
-
},
|
|
79
|
+
}, ue = (e) => {
|
|
79
80
|
F((t) => t.includes(e) ? t.filter((t) => t !== e) : [...t, e]);
|
|
80
81
|
}, Z = (e) => {
|
|
81
82
|
switch (e) {
|
|
82
|
-
case "INDIVIDUAL": return
|
|
83
|
-
case "WORKSPACE_ADMIN": return
|
|
84
|
-
case "ORG_ADMIN": return
|
|
83
|
+
case "INDIVIDUAL": return y("export.create.scope.individual.label", "My Data Only");
|
|
84
|
+
case "WORKSPACE_ADMIN": return y("export.create.scope.workspaceAdmin.label", "All Workspace Data");
|
|
85
|
+
case "ORG_ADMIN": return y("export.create.scope.orgAdmin.label", "All Organization Data");
|
|
85
86
|
default: return e;
|
|
86
87
|
}
|
|
87
|
-
},
|
|
88
|
+
}, de = (e) => {
|
|
88
89
|
switch (e) {
|
|
89
|
-
case "INDIVIDUAL": return
|
|
90
|
-
case "WORKSPACE_ADMIN": return
|
|
91
|
-
case "ORG_ADMIN": return
|
|
90
|
+
case "INDIVIDUAL": return y("export.create.scope.individual.description", "Export data you personally created across selected modules.");
|
|
91
|
+
case "WORKSPACE_ADMIN": return y("export.create.scope.workspaceAdmin.description", "Export all data in this workspace regardless of who created it. Requires workspace admin access.");
|
|
92
|
+
case "ORG_ADMIN": return y("export.create.scope.orgAdmin.description", "Export data from every workspace in your organization. Requires org-admin access.");
|
|
92
93
|
default: return "";
|
|
93
94
|
}
|
|
94
95
|
}, Q = {
|
|
95
96
|
users: {
|
|
96
|
-
label:
|
|
97
|
-
description:
|
|
97
|
+
label: y("export.create.entities.users.label", "Users"),
|
|
98
|
+
description: y("export.create.entities.users.description", "Workspace members and profiles")
|
|
98
99
|
},
|
|
99
100
|
projects: {
|
|
100
|
-
label:
|
|
101
|
-
description:
|
|
101
|
+
label: y("export.create.entities.projects.label", "Projects"),
|
|
102
|
+
description: y("export.create.entities.projects.description", "Projects and their metadata")
|
|
102
103
|
},
|
|
103
104
|
tasks: {
|
|
104
|
-
label:
|
|
105
|
-
description:
|
|
105
|
+
label: y("export.create.entities.tasks.label", "Tasks"),
|
|
106
|
+
description: y("export.create.entities.tasks.description", "Task items and assignments")
|
|
106
107
|
},
|
|
107
108
|
files: {
|
|
108
|
-
label:
|
|
109
|
-
description:
|
|
109
|
+
label: y("export.create.entities.files.label", "Files"),
|
|
110
|
+
description: y("export.create.entities.files.description", "File metadata and references")
|
|
110
111
|
},
|
|
111
112
|
conversations: {
|
|
112
|
-
label:
|
|
113
|
-
description:
|
|
113
|
+
label: y("export.create.entities.conversations.label", "Conversations"),
|
|
114
|
+
description: y("export.create.entities.conversations.description", "Chat messages and threads")
|
|
114
115
|
},
|
|
115
116
|
tags: {
|
|
116
|
-
label:
|
|
117
|
-
description:
|
|
117
|
+
label: y("export.create.entities.tags.label", "Tags"),
|
|
118
|
+
description: y("export.create.entities.tags.description", "Tags and vocabularies")
|
|
118
119
|
},
|
|
119
120
|
activity: {
|
|
120
|
-
label:
|
|
121
|
-
description:
|
|
121
|
+
label: y("export.create.entities.activity.label", "Activity Logs"),
|
|
122
|
+
description: y("export.create.entities.activity.description", "Audit trail and activity history")
|
|
122
123
|
},
|
|
123
124
|
calendar: {
|
|
124
|
-
label:
|
|
125
|
-
description:
|
|
125
|
+
label: y("export.create.entities.calendar.label", "Calendar Events"),
|
|
126
|
+
description: y("export.create.entities.calendar.description", "Events and bookings")
|
|
126
127
|
}
|
|
127
|
-
}, $ =
|
|
128
|
-
return /* @__PURE__ */
|
|
128
|
+
}, $ = O.filter((e) => e.enabled !== !1);
|
|
129
|
+
return /* @__PURE__ */ S(ee, {
|
|
129
130
|
showHeader: !1,
|
|
130
131
|
children: [
|
|
131
|
-
/* @__PURE__ */
|
|
132
|
+
/* @__PURE__ */ x("div", {
|
|
132
133
|
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",
|
|
133
|
-
children: /* @__PURE__ */
|
|
134
|
+
children: /* @__PURE__ */ S("div", {
|
|
134
135
|
className: "relative z-10 flex items-center gap-4",
|
|
135
|
-
children: [/* @__PURE__ */
|
|
136
|
-
onClick: () =>
|
|
136
|
+
children: [/* @__PURE__ */ x("button", {
|
|
137
|
+
onClick: () => m?.(d),
|
|
137
138
|
className: "p-2.5 hover:bg-accent rounded-lg transition-all duration-200 hover:scale-110",
|
|
138
|
-
"aria-label":
|
|
139
|
-
children: /* @__PURE__ */
|
|
140
|
-
}), /* @__PURE__ */
|
|
139
|
+
"aria-label": y("export.create.actions.backToDashboard", "Back to export dashboard"),
|
|
140
|
+
children: /* @__PURE__ */ x(l, { size: 20 })
|
|
141
|
+
}), /* @__PURE__ */ S("div", {
|
|
141
142
|
className: "flex items-center gap-3",
|
|
142
|
-
children: [/* @__PURE__ */
|
|
143
|
+
children: [/* @__PURE__ */ x("div", {
|
|
143
144
|
className: "p-2.5 rounded-lg bg-primary/10 backdrop-blur-sm",
|
|
144
|
-
children: /* @__PURE__ */
|
|
145
|
+
children: /* @__PURE__ */ x(p, {
|
|
145
146
|
size: 24,
|
|
146
147
|
className: "text-primary"
|
|
147
148
|
})
|
|
148
|
-
}), /* @__PURE__ */
|
|
149
|
+
}), /* @__PURE__ */ x("h1", {
|
|
149
150
|
className: "text-2xl sm:text-3xl font-bold",
|
|
150
|
-
children:
|
|
151
|
+
children: y("export.create.title", "New Export")
|
|
151
152
|
})]
|
|
152
153
|
})]
|
|
153
154
|
})
|
|
154
155
|
}),
|
|
155
|
-
/* @__PURE__ */
|
|
156
|
+
/* @__PURE__ */ x("div", {
|
|
156
157
|
className: "flex items-center gap-2 justify-center flex-wrap",
|
|
157
158
|
children: [
|
|
158
159
|
"entities",
|
|
159
160
|
"options",
|
|
160
161
|
"review"
|
|
161
|
-
].map((e, t) => /* @__PURE__ */
|
|
162
|
+
].map((e, t) => /* @__PURE__ */ S("div", {
|
|
162
163
|
className: "flex items-center gap-2",
|
|
163
|
-
children: [t > 0 && /* @__PURE__ */
|
|
164
|
+
children: [t > 0 && /* @__PURE__ */ x(u, {
|
|
164
165
|
size: 18,
|
|
165
166
|
className: "text-muted-foreground"
|
|
166
|
-
}), /* @__PURE__ */
|
|
167
|
+
}), /* @__PURE__ */ S("div", {
|
|
167
168
|
className: i("flex items-center gap-2 px-4 py-2.5 rounded-lg text-sm font-medium border-2 transition-all duration-200", M === e ? "bg-primary text-primary-foreground border-primary shadow-md scale-105" : "bg-muted/50 text-muted-foreground border-border/50"),
|
|
168
|
-
children: [/* @__PURE__ */
|
|
169
|
+
children: [/* @__PURE__ */ x("div", {
|
|
169
170
|
className: "flex items-center justify-center w-6 h-6 rounded-full bg-background/20 font-bold",
|
|
170
171
|
children: t + 1
|
|
171
|
-
}), /* @__PURE__ */
|
|
172
|
+
}), /* @__PURE__ */ x("span", {
|
|
172
173
|
className: "hidden sm:inline capitalize",
|
|
173
|
-
children: e === "entities" ?
|
|
174
|
+
children: e === "entities" ? y("export.create.steps.entities", "Select Data") : e === "options" ? y("export.create.steps.options", "Options") : y("export.create.steps.review", "Review")
|
|
174
175
|
})]
|
|
175
176
|
})]
|
|
176
177
|
}, e))
|
|
177
178
|
}),
|
|
178
|
-
|
|
179
|
+
q && /* @__PURE__ */ x("div", {
|
|
179
180
|
className: "border-2 border-border-default rounded-xl bg-status-error-bg-subtle p-4 text-status-error-text text-sm",
|
|
180
|
-
children:
|
|
181
|
+
children: q
|
|
181
182
|
}),
|
|
182
|
-
M === "entities" && /* @__PURE__ */
|
|
183
|
+
M === "entities" && /* @__PURE__ */ S("div", {
|
|
183
184
|
className: "space-y-4",
|
|
184
185
|
children: [
|
|
185
|
-
/* @__PURE__ */
|
|
186
|
+
/* @__PURE__ */ x("h2", {
|
|
186
187
|
className: "text-lg font-bold",
|
|
187
|
-
children:
|
|
188
|
+
children: y("export.create.select.title", "Select data to export")
|
|
188
189
|
}),
|
|
189
|
-
/* @__PURE__ */
|
|
190
|
+
/* @__PURE__ */ x("p", {
|
|
190
191
|
className: "text-sm text-muted-foreground",
|
|
191
|
-
children:
|
|
192
|
+
children: y("export.create.select.description", "Choose which entity types to include in your export.")
|
|
192
193
|
}),
|
|
193
|
-
$.length === 0 ? /* @__PURE__ */
|
|
194
|
+
$.length === 0 ? /* @__PURE__ */ x("div", {
|
|
194
195
|
className: "border-2 border-border rounded-xl bg-muted/30 p-6 text-sm text-muted-foreground",
|
|
195
|
-
children:
|
|
196
|
-
}) : /* @__PURE__ */
|
|
196
|
+
children: y("export.create.select.empty", "No exportable entity types are configured for this workspace yet.")
|
|
197
|
+
}) : /* @__PURE__ */ x("div", {
|
|
197
198
|
className: "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-3",
|
|
198
199
|
children: $.map((e) => {
|
|
199
200
|
let t = P.includes(e.entityType);
|
|
200
|
-
return /* @__PURE__ */
|
|
201
|
-
onClick: () =>
|
|
201
|
+
return /* @__PURE__ */ S("button", {
|
|
202
|
+
onClick: () => ue(e.entityType),
|
|
202
203
|
className: i("text-left border-2 rounded-xl p-4 transition-all duration-200", t ? "border-primary bg-primary/5 shadow-md" : "border-border/50 hover:border-primary/30 hover:shadow-sm"),
|
|
203
204
|
children: [
|
|
204
|
-
/* @__PURE__ */
|
|
205
|
+
/* @__PURE__ */ S("div", {
|
|
205
206
|
className: "flex items-center justify-between mb-2",
|
|
206
|
-
children: [/* @__PURE__ */
|
|
207
|
+
children: [/* @__PURE__ */ x("h3", {
|
|
207
208
|
className: "font-semibold",
|
|
208
209
|
children: Q[e.entityType]?.label ?? e.displayName
|
|
209
|
-
}), t && /* @__PURE__ */
|
|
210
|
+
}), t && /* @__PURE__ */ x(f, {
|
|
210
211
|
size: 18,
|
|
211
212
|
className: "text-primary"
|
|
212
213
|
})]
|
|
213
214
|
}),
|
|
214
|
-
/* @__PURE__ */
|
|
215
|
+
/* @__PURE__ */ x("p", {
|
|
215
216
|
className: "text-sm text-muted-foreground",
|
|
216
217
|
children: Q[e.entityType]?.description ?? e.description
|
|
217
218
|
}),
|
|
218
|
-
e.estimatedSize && /* @__PURE__ */
|
|
219
|
+
e.estimatedSize && /* @__PURE__ */ S("p", {
|
|
219
220
|
className: "text-xs text-muted-foreground mt-2",
|
|
220
221
|
children: ["~", e.estimatedSize]
|
|
221
222
|
})
|
|
@@ -225,240 +226,252 @@ function D() {
|
|
|
225
226
|
})
|
|
226
227
|
]
|
|
227
228
|
}),
|
|
228
|
-
M === "options" && /* @__PURE__ */
|
|
229
|
+
M === "options" && /* @__PURE__ */ x("div", {
|
|
229
230
|
className: "space-y-6",
|
|
230
|
-
children: /* @__PURE__ */
|
|
231
|
+
children: /* @__PURE__ */ S("div", {
|
|
231
232
|
className: "border-2 border-border/50 rounded-xl p-6 space-y-5",
|
|
232
233
|
children: [
|
|
233
|
-
/* @__PURE__ */
|
|
234
|
+
/* @__PURE__ */ x("h2", {
|
|
234
235
|
className: "text-lg font-bold",
|
|
235
|
-
children:
|
|
236
|
+
children: y("export.create.options.title", "Export Options")
|
|
236
237
|
}),
|
|
237
|
-
/* @__PURE__ */
|
|
238
|
+
/* @__PURE__ */ S("div", { children: [/* @__PURE__ */ x("label", {
|
|
238
239
|
className: "block text-sm font-semibold mb-2",
|
|
239
|
-
children:
|
|
240
|
-
}), /* @__PURE__ */
|
|
240
|
+
children: y("export.create.options.scope", "Export Scope")
|
|
241
|
+
}), /* @__PURE__ */ x("div", {
|
|
241
242
|
className: "grid grid-cols-1 sm:grid-cols-3 gap-3",
|
|
242
|
-
children:
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
243
|
+
children: ae.map(({ value: e, Icon: t }) => {
|
|
244
|
+
let n = e === "WORKSPACE_ADMIN" && !j || e === "ORG_ADMIN" && !oe;
|
|
245
|
+
return /* @__PURE__ */ S("button", {
|
|
246
|
+
type: "button",
|
|
247
|
+
onClick: () => !n && V(e),
|
|
248
|
+
disabled: n,
|
|
249
|
+
className: i("text-left border-2 rounded-xl p-4 transition-all duration-200", B === e ? "border-primary bg-primary/5 shadow-md" : n ? "border-border/30 opacity-50 cursor-not-allowed" : "border-border/50 hover:border-primary/30 hover:shadow-sm"),
|
|
250
|
+
title: n ? e === "WORKSPACE_ADMIN" ? "Workspace admin access required" : "Organization admin access required" : void 0,
|
|
251
|
+
children: [
|
|
252
|
+
/* @__PURE__ */ S("div", {
|
|
253
|
+
className: "flex items-center justify-between mb-2",
|
|
254
|
+
children: [
|
|
255
|
+
/* @__PURE__ */ x(t, {
|
|
256
|
+
size: 18,
|
|
257
|
+
className: B === e ? "text-primary" : n ? "text-muted-foreground/50" : "text-muted-foreground"
|
|
258
|
+
}),
|
|
259
|
+
B === e && /* @__PURE__ */ x(f, {
|
|
260
|
+
size: 16,
|
|
261
|
+
className: "text-primary"
|
|
262
|
+
}),
|
|
263
|
+
n && /* @__PURE__ */ x(_, {
|
|
264
|
+
size: 14,
|
|
265
|
+
className: "text-muted-foreground/50"
|
|
266
|
+
})
|
|
267
|
+
]
|
|
268
|
+
}),
|
|
269
|
+
/* @__PURE__ */ x("p", {
|
|
270
|
+
className: "font-semibold text-sm",
|
|
271
|
+
children: Z(e)
|
|
272
|
+
}),
|
|
273
|
+
/* @__PURE__ */ x("p", {
|
|
274
|
+
className: "text-xs text-muted-foreground mt-1",
|
|
275
|
+
children: de(e)
|
|
276
|
+
})
|
|
277
|
+
]
|
|
278
|
+
}, e);
|
|
279
|
+
})
|
|
267
280
|
})] }),
|
|
268
|
-
/* @__PURE__ */
|
|
281
|
+
/* @__PURE__ */ S("div", { children: [/* @__PURE__ */ S("label", {
|
|
269
282
|
htmlFor: "exportName",
|
|
270
283
|
className: "block text-sm font-semibold mb-2",
|
|
271
284
|
children: [
|
|
272
|
-
|
|
285
|
+
y("export.create.options.name", "Export Name"),
|
|
273
286
|
" ",
|
|
274
|
-
/* @__PURE__ */
|
|
287
|
+
/* @__PURE__ */ x("span", {
|
|
275
288
|
className: "text-status-error-text",
|
|
276
289
|
children: "*"
|
|
277
290
|
})
|
|
278
291
|
]
|
|
279
|
-
}), /* @__PURE__ */
|
|
292
|
+
}), /* @__PURE__ */ x("input", {
|
|
280
293
|
type: "text",
|
|
281
294
|
id: "exportName",
|
|
282
295
|
value: I,
|
|
283
296
|
onChange: (e) => L(e.target.value),
|
|
284
297
|
className: "w-full px-4 py-2.5 border-2 border-border rounded-lg bg-background focus:outline-none focus:ring-2 focus:ring-primary/20 focus:border-primary transition-all duration-200",
|
|
285
|
-
placeholder:
|
|
298
|
+
placeholder: y("export.create.options.namePlaceholder", "e.g., Monthly User Export")
|
|
286
299
|
})] }),
|
|
287
|
-
/* @__PURE__ */
|
|
300
|
+
/* @__PURE__ */ S("div", { children: [/* @__PURE__ */ x("label", {
|
|
288
301
|
className: "block text-sm font-semibold mb-2",
|
|
289
|
-
children:
|
|
290
|
-
}), /* @__PURE__ */
|
|
302
|
+
children: y("export.create.options.outputFormat", "Output Format")
|
|
303
|
+
}), /* @__PURE__ */ x("div", {
|
|
291
304
|
className: "grid grid-cols-2 gap-3",
|
|
292
|
-
children:
|
|
293
|
-
let t =
|
|
294
|
-
return /* @__PURE__ */
|
|
305
|
+
children: T.map((e) => {
|
|
306
|
+
let t = ie[e];
|
|
307
|
+
return /* @__PURE__ */ S("button", {
|
|
295
308
|
onClick: () => z(e),
|
|
296
309
|
className: i("flex items-center gap-3 border-2 rounded-lg p-3 transition-all duration-200", R === e ? "border-primary bg-primary/5" : "border-border/50 hover:border-primary/30"),
|
|
297
|
-
children: [/* @__PURE__ */
|
|
310
|
+
children: [/* @__PURE__ */ x(t, {
|
|
298
311
|
size: 18,
|
|
299
312
|
className: R === e ? "text-primary" : "text-muted-foreground"
|
|
300
|
-
}), /* @__PURE__ */
|
|
313
|
+
}), /* @__PURE__ */ x("span", {
|
|
301
314
|
className: "font-medium text-sm",
|
|
302
315
|
children: a(e)
|
|
303
316
|
})]
|
|
304
317
|
}, e);
|
|
305
318
|
})
|
|
306
319
|
})] }),
|
|
307
|
-
/* @__PURE__ */
|
|
308
|
-
/* @__PURE__ */
|
|
320
|
+
/* @__PURE__ */ S("div", { children: [
|
|
321
|
+
/* @__PURE__ */ x("label", {
|
|
309
322
|
className: "block text-sm font-semibold mb-2",
|
|
310
|
-
children:
|
|
323
|
+
children: y("export.create.options.archiveFormat", "Archive Format")
|
|
311
324
|
}),
|
|
312
|
-
/* @__PURE__ */
|
|
325
|
+
/* @__PURE__ */ x("div", {
|
|
313
326
|
className: "flex gap-3",
|
|
314
|
-
children: /* @__PURE__ */
|
|
327
|
+
children: /* @__PURE__ */ S("div", {
|
|
315
328
|
className: i("flex items-center gap-2 border-2 rounded-lg px-4 py-2 border-primary bg-primary/5"),
|
|
316
|
-
children: [/* @__PURE__ */
|
|
329
|
+
children: [/* @__PURE__ */ x(re, {
|
|
317
330
|
size: 16,
|
|
318
331
|
className: "text-primary"
|
|
319
|
-
}), /* @__PURE__ */
|
|
332
|
+
}), /* @__PURE__ */ x("span", {
|
|
320
333
|
className: "font-medium text-sm",
|
|
321
334
|
children: "ZIP"
|
|
322
335
|
})]
|
|
323
336
|
})
|
|
324
337
|
}),
|
|
325
|
-
/* @__PURE__ */
|
|
338
|
+
/* @__PURE__ */ x("p", {
|
|
326
339
|
className: "text-xs text-muted-foreground mt-1.5",
|
|
327
|
-
children:
|
|
340
|
+
children: y("export.create.options.archiveDescription", "Exports are packaged as ZIP archives.")
|
|
328
341
|
})
|
|
329
342
|
] }),
|
|
330
|
-
/* @__PURE__ */
|
|
331
|
-
/* @__PURE__ */
|
|
343
|
+
/* @__PURE__ */ S("div", { children: [
|
|
344
|
+
/* @__PURE__ */ x("label", {
|
|
332
345
|
className: "block text-sm font-semibold mb-2",
|
|
333
|
-
children: /* @__PURE__ */
|
|
346
|
+
children: /* @__PURE__ */ S("span", {
|
|
334
347
|
className: "inline-flex items-center gap-1.5",
|
|
335
348
|
children: [
|
|
336
|
-
/* @__PURE__ */
|
|
337
|
-
|
|
349
|
+
/* @__PURE__ */ x(ne, { size: 15 }),
|
|
350
|
+
y("export.create.options.dateRange", "Date Range"),
|
|
338
351
|
" ",
|
|
339
|
-
/* @__PURE__ */
|
|
352
|
+
/* @__PURE__ */ x("span", {
|
|
340
353
|
className: "font-normal text-muted-foreground",
|
|
341
|
-
children:
|
|
354
|
+
children: y("export.create.shared.optional", "(optional)")
|
|
342
355
|
})
|
|
343
356
|
]
|
|
344
357
|
})
|
|
345
358
|
}),
|
|
346
|
-
/* @__PURE__ */
|
|
359
|
+
/* @__PURE__ */ S("div", {
|
|
347
360
|
className: "grid grid-cols-1 sm:grid-cols-2 gap-3",
|
|
348
|
-
children: [/* @__PURE__ */
|
|
361
|
+
children: [/* @__PURE__ */ S("div", { children: [/* @__PURE__ */ x("label", {
|
|
349
362
|
htmlFor: "dateFrom",
|
|
350
363
|
className: "block text-xs text-muted-foreground mb-1",
|
|
351
|
-
children:
|
|
352
|
-
}), /* @__PURE__ */
|
|
364
|
+
children: y("export.create.options.dateFrom", "From")
|
|
365
|
+
}), /* @__PURE__ */ x("input", {
|
|
353
366
|
type: "date",
|
|
354
367
|
id: "dateFrom",
|
|
355
368
|
value: W,
|
|
356
369
|
onChange: (e) => G(e.target.value),
|
|
357
370
|
className: "w-full px-3 py-2 border-2 border-border rounded-lg bg-background focus:outline-none focus:ring-2 focus:ring-primary/20 focus:border-primary text-sm"
|
|
358
|
-
})] }), /* @__PURE__ */
|
|
371
|
+
})] }), /* @__PURE__ */ S("div", { children: [/* @__PURE__ */ x("label", {
|
|
359
372
|
htmlFor: "dateTo",
|
|
360
373
|
className: "block text-xs text-muted-foreground mb-1",
|
|
361
|
-
children:
|
|
362
|
-
}), /* @__PURE__ */
|
|
374
|
+
children: y("export.create.options.dateTo", "To")
|
|
375
|
+
}), /* @__PURE__ */ x("input", {
|
|
363
376
|
type: "date",
|
|
364
377
|
id: "dateTo",
|
|
365
378
|
value: K,
|
|
366
379
|
min: W,
|
|
367
|
-
onChange: (e) =>
|
|
380
|
+
onChange: (e) => se(e.target.value),
|
|
368
381
|
className: "w-full px-3 py-2 border-2 border-border rounded-lg bg-background focus:outline-none focus:ring-2 focus:ring-primary/20 focus:border-primary text-sm"
|
|
369
382
|
})] })]
|
|
370
383
|
}),
|
|
371
|
-
/* @__PURE__ */
|
|
384
|
+
/* @__PURE__ */ x("p", {
|
|
372
385
|
className: "text-xs text-muted-foreground mt-1.5",
|
|
373
|
-
children:
|
|
386
|
+
children: y("export.create.options.dateRangeDescription", "Leave blank to export all data regardless of date.")
|
|
374
387
|
})
|
|
375
388
|
] }),
|
|
376
|
-
/* @__PURE__ */
|
|
389
|
+
/* @__PURE__ */ S("div", { children: [/* @__PURE__ */ S("label", {
|
|
377
390
|
className: "block text-sm font-semibold mb-2",
|
|
378
391
|
children: [
|
|
379
|
-
|
|
392
|
+
y("export.create.options.basedOnTemplate", "Based on Template"),
|
|
380
393
|
" ",
|
|
381
|
-
/* @__PURE__ */
|
|
394
|
+
/* @__PURE__ */ x("span", {
|
|
382
395
|
className: "font-normal text-muted-foreground",
|
|
383
|
-
children:
|
|
396
|
+
children: y("export.create.shared.optional", "(optional)")
|
|
384
397
|
})
|
|
385
398
|
]
|
|
386
|
-
}),
|
|
399
|
+
}), k.length > 0 ? /* @__PURE__ */ S("select", {
|
|
387
400
|
value: H ?? "",
|
|
388
401
|
onChange: (e) => U(e.target.value || void 0),
|
|
389
402
|
className: "w-full px-3 py-2 border-2 border-border rounded-lg bg-background focus:outline-none focus:ring-2 focus:ring-primary/20 focus:border-primary",
|
|
390
|
-
children: [/* @__PURE__ */
|
|
403
|
+
children: [/* @__PURE__ */ x("option", {
|
|
391
404
|
value: "",
|
|
392
|
-
children:
|
|
393
|
-
}),
|
|
405
|
+
children: y("export.create.options.noTemplate", "No template")
|
|
406
|
+
}), k.map((e) => /* @__PURE__ */ x("option", {
|
|
394
407
|
value: e.id,
|
|
395
408
|
children: e.name
|
|
396
409
|
}, e.id))]
|
|
397
|
-
}) : /* @__PURE__ */
|
|
410
|
+
}) : /* @__PURE__ */ S("p", {
|
|
398
411
|
className: "text-sm text-muted-foreground",
|
|
399
412
|
children: [
|
|
400
|
-
|
|
413
|
+
y("export.create.options.noTemplates", "No templates yet."),
|
|
401
414
|
" ",
|
|
402
|
-
/* @__PURE__ */
|
|
415
|
+
/* @__PURE__ */ x("button", {
|
|
403
416
|
type: "button",
|
|
404
|
-
onClick: () =>
|
|
417
|
+
onClick: () => m?.(d + "/templates"),
|
|
405
418
|
className: "text-primary underline-offset-2 hover:underline",
|
|
406
|
-
children:
|
|
419
|
+
children: y("export.create.options.createTemplateLink", "Create one")
|
|
407
420
|
}),
|
|
408
421
|
" ",
|
|
409
|
-
|
|
422
|
+
y("export.create.options.reuseTemplateHint", "to reuse export configurations.")
|
|
410
423
|
]
|
|
411
424
|
})] })
|
|
412
425
|
]
|
|
413
426
|
})
|
|
414
427
|
}),
|
|
415
|
-
M === "review" && /* @__PURE__ */
|
|
428
|
+
M === "review" && /* @__PURE__ */ x("div", {
|
|
416
429
|
className: "space-y-6",
|
|
417
|
-
children: /* @__PURE__ */
|
|
430
|
+
children: /* @__PURE__ */ S("div", {
|
|
418
431
|
className: "border-2 border-primary/50 rounded-xl bg-primary/5 p-6 space-y-4",
|
|
419
|
-
children: [/* @__PURE__ */
|
|
432
|
+
children: [/* @__PURE__ */ S("h2", {
|
|
420
433
|
className: "text-lg font-bold flex items-center gap-2",
|
|
421
|
-
children: [/* @__PURE__ */
|
|
434
|
+
children: [/* @__PURE__ */ x(f, {
|
|
422
435
|
size: 20,
|
|
423
436
|
className: "text-primary"
|
|
424
|
-
}),
|
|
425
|
-
}), /* @__PURE__ */
|
|
437
|
+
}), y("export.create.review.title", "Review Export")]
|
|
438
|
+
}), /* @__PURE__ */ x("dl", {
|
|
426
439
|
className: "space-y-3 text-sm",
|
|
427
440
|
children: [
|
|
428
441
|
{
|
|
429
|
-
label:
|
|
442
|
+
label: y("export.create.review.fields.name", "Name"),
|
|
430
443
|
value: I
|
|
431
444
|
},
|
|
432
445
|
{
|
|
433
|
-
label:
|
|
446
|
+
label: y("export.create.review.fields.scope", "Scope"),
|
|
434
447
|
value: Z(B)
|
|
435
448
|
},
|
|
436
449
|
{
|
|
437
|
-
label:
|
|
450
|
+
label: y("export.create.review.fields.entityTypes", "Entity Types"),
|
|
438
451
|
value: P.join(", ")
|
|
439
452
|
},
|
|
440
453
|
{
|
|
441
|
-
label:
|
|
454
|
+
label: y("export.create.review.fields.format", "Format"),
|
|
442
455
|
value: a(R)
|
|
443
456
|
},
|
|
444
457
|
{
|
|
445
|
-
label:
|
|
458
|
+
label: y("export.create.review.fields.archive", "Archive"),
|
|
446
459
|
value: "ZIP"
|
|
447
460
|
},
|
|
448
461
|
...W || K ? [{
|
|
449
|
-
label:
|
|
462
|
+
label: y("export.create.review.fields.dateRange", "Date Range"),
|
|
450
463
|
value: [W || "—", K || "—"].join(" → ")
|
|
451
464
|
}] : [],
|
|
452
465
|
...H ? [{
|
|
453
|
-
label:
|
|
454
|
-
value:
|
|
466
|
+
label: y("export.create.review.fields.template", "Template"),
|
|
467
|
+
value: k.find((e) => e.id === H)?.name ?? H
|
|
455
468
|
}] : []
|
|
456
|
-
].map(({ label: e, value: t }) => /* @__PURE__ */
|
|
469
|
+
].map(({ label: e, value: t }) => /* @__PURE__ */ S("div", {
|
|
457
470
|
className: "flex flex-col sm:flex-row sm:justify-between gap-1",
|
|
458
|
-
children: [/* @__PURE__ */
|
|
471
|
+
children: [/* @__PURE__ */ x("dt", {
|
|
459
472
|
className: "text-muted-foreground",
|
|
460
473
|
children: e
|
|
461
|
-
}), /* @__PURE__ */
|
|
474
|
+
}), /* @__PURE__ */ x("dd", {
|
|
462
475
|
className: "font-semibold sm:text-right break-words",
|
|
463
476
|
children: t
|
|
464
477
|
})]
|
|
@@ -466,30 +479,30 @@ function D() {
|
|
|
466
479
|
})]
|
|
467
480
|
})
|
|
468
481
|
}),
|
|
469
|
-
/* @__PURE__ */
|
|
482
|
+
/* @__PURE__ */ S("div", {
|
|
470
483
|
className: "flex flex-col sm:flex-row gap-3 pt-2",
|
|
471
|
-
children: [/* @__PURE__ */
|
|
472
|
-
onClick:
|
|
484
|
+
children: [/* @__PURE__ */ x("button", {
|
|
485
|
+
onClick: ce,
|
|
473
486
|
className: "px-6 py-3 border-2 border-border/50 rounded-lg hover:bg-accent hover:border-primary/30 transition-all duration-200 font-medium",
|
|
474
|
-
children: M === "entities" ?
|
|
475
|
-
}), M === "review" ? /* @__PURE__ */
|
|
476
|
-
onClick:
|
|
477
|
-
disabled:
|
|
487
|
+
children: M === "entities" ? y("export.create.actions.cancel", "Cancel") : y("export.create.actions.back", "Back")
|
|
488
|
+
}), M === "review" ? /* @__PURE__ */ S("button", {
|
|
489
|
+
onClick: le,
|
|
490
|
+
disabled: D,
|
|
478
491
|
className: "flex-1 inline-flex items-center justify-center gap-2 px-6 py-3 bg-primary text-primary-foreground rounded-lg hover:bg-primary/90 transition-all duration-200 hover:scale-105 font-bold shadow-lg disabled:opacity-50 disabled:cursor-not-allowed",
|
|
479
|
-
children: [
|
|
492
|
+
children: [D ? /* @__PURE__ */ x(g, {
|
|
480
493
|
size: 18,
|
|
481
494
|
className: "animate-spin"
|
|
482
|
-
}) : /* @__PURE__ */
|
|
483
|
-
}) : /* @__PURE__ */
|
|
484
|
-
onClick:
|
|
495
|
+
}) : /* @__PURE__ */ x(p, { size: 18 }), y("export.create.actions.startExport", "Start Export")]
|
|
496
|
+
}) : /* @__PURE__ */ S("button", {
|
|
497
|
+
onClick: X,
|
|
485
498
|
className: "flex-1 inline-flex items-center justify-center gap-2 px-6 py-3 bg-primary text-primary-foreground rounded-lg hover:bg-primary/90 transition-all duration-200 hover:scale-105 font-bold shadow-lg",
|
|
486
|
-
children: [
|
|
499
|
+
children: [y("export.create.actions.next", "Next"), /* @__PURE__ */ x(u, { size: 18 })]
|
|
487
500
|
})]
|
|
488
501
|
})
|
|
489
502
|
]
|
|
490
503
|
});
|
|
491
504
|
}
|
|
492
505
|
//#endregion
|
|
493
|
-
export {
|
|
506
|
+
export { E as CreateExportPage };
|
|
494
507
|
|
|
495
508
|
//# sourceMappingURL=CreateExportPage.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CreateExportPage.js","names":[],"sources":["../../../src/export/pages/CreateExportPage.tsx"],"sourcesContent":["import { useState, useEffect, useRef } from \"react\";\nimport { useSearchParams } from \"react-router-dom\";\nimport {\n ArrowLeft,\n ArrowRight,\n Download,\n CheckCircle2,\n Loader2,\n FileSpreadsheet,\n FileJson,\n Package,\n CalendarRange,\n User,\n Users,\n Building2,\n} from \"lucide-react\";\nimport { useI18n } from \"@burdenoff/fe-libs/shared/providers/shell/I18nProvider\";\nimport { useExport } from \"../providers/ExportProvider\";\nimport {\n useCreateExportJob,\n useAvailableEntities,\n useExportTemplates,\n} from \"../hooks/useExportQueries\";\nimport { getFormatDisplayName } from \"../constants/enums\";\nimport { PageLayout } from \"../components/PageLayout\";\nimport { cn } from \"../utils/cn\";\nimport type { ExportFormat, ExportScope } from \"../types\";\nimport { tWithFallback } from \"../utils/i18n\";\n\ntype WizardStep = \"entities\" | \"options\" | \"review\";\n\n// Backend only supports CSV and JSON\nconst SUPPORTED_FORMATS: ExportFormat[] = [\"CSV\", \"JSON\"];\n\nconst FORMAT_ICONS: Record<ExportFormat, typeof FileJson> = {\n CSV: FileSpreadsheet,\n JSON: FileJson,\n};\n\n/**\n * Create Export Page\n * Multi-step form: select entities, configure options, review & start\n */\nconst SCOPE_OPTIONS: Array<{\n value: ExportScope;\n label: string;\n description: string;\n Icon: typeof User;\n}> = [\n {\n value: \"INDIVIDUAL\",\n label: \"My Data Only\",\n description: \"Export data you personally created across selected modules.\",\n Icon: User,\n },\n {\n value: \"WORKSPACE_ADMIN\",\n label: \"All Workspace Data\",\n description:\n \"Export all data in this workspace regardless of who created it. Requires workspace admin access.\",\n Icon: Users,\n },\n {\n value: \"ORG_ADMIN\",\n label: \"All Organization Data\",\n description:\n \"Export data from every workspace in your organization. Requires org-admin access.\",\n Icon: Building2,\n },\n];\n\nexport function CreateExportPage() {\n const { basePath = \"/\", navigate, organizationId } = 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 { createJob, isPending } = useCreateExportJob();\n const { data: availableEntities } = useAvailableEntities();\n const { data: templates } = useExportTemplates();\n const [searchParams] = useSearchParams();\n\n const [step, setStep] = useState<WizardStep>(\"entities\");\n const [selectedEntities, setSelectedEntities] = useState<string[]>([]);\n const [exportName, setExportName] = useState(\"\");\n const [selectedFormat, setSelectedFormat] = useState<ExportFormat>(\"CSV\");\n const [selectedScope, setSelectedScope] = useState<ExportScope>(\"INDIVIDUAL\");\n const [selectedTemplateId, setSelectedTemplateId] = useState<\n string | undefined\n >(searchParams.get(\"templateId\") ?? undefined);\n const [dateRangeStart, setDateRangeStart] = useState(\"\");\n const [dateRangeEnd, setDateRangeEnd] = useState(\"\");\n const [error, setError] = useState<string | null>(null);\n\n // Pre-populate form when arriving from \"Use Template\" — apply only once per templateId\n const appliedTemplateRef = useRef<string | null>(null);\n useEffect(() => {\n const paramTemplateId = searchParams.get(\"templateId\");\n if (!paramTemplateId || !templates?.length) return;\n if (appliedTemplateRef.current === paramTemplateId) return;\n const tpl = templates.find((t) => t.id === paramTemplateId);\n if (!tpl) return;\n appliedTemplateRef.current = paramTemplateId;\n setSelectedTemplateId(tpl.id);\n setSelectedEntities(tpl.entityTypes ?? []);\n const normalizedFormat = tpl.format?.toUpperCase() as\n | ExportFormat\n | undefined;\n if (normalizedFormat && SUPPORTED_FORMATS.includes(normalizedFormat)) {\n setSelectedFormat(normalizedFormat);\n }\n if (tpl.name) setExportName(tpl.name);\n }, [searchParams, templates]);\n\n const handleBack = () => {\n if (step === \"options\") setStep(\"entities\");\n else if (step === \"review\") setStep(\"options\");\n else navigate?.(basePath);\n };\n\n const handleNext = () => {\n if (step === \"entities\") {\n if (selectedEntities.length === 0) {\n setError(\n tr(\n \"export.create.errors.selectEntity\",\n \"Please select at least one entity type to export\",\n ),\n );\n return;\n }\n setError(null);\n setStep(\"options\");\n } else if (step === \"options\") {\n if (!exportName.trim()) {\n setError(\n tr(\n \"export.create.errors.exportNameRequired\",\n \"Please provide a name for this export\",\n ),\n );\n return;\n }\n setError(null);\n setStep(\"review\");\n }\n };\n\n const handleSubmit = async () => {\n try {\n setError(null);\n await createJob({\n name: exportName,\n entityTypes: selectedEntities,\n format: selectedFormat,\n exportScope: selectedScope,\n organizationId:\n selectedScope === \"ORG_ADMIN\" ? organizationId : undefined,\n templateId: selectedTemplateId,\n dateRangeStart: dateRangeStart\n ? new Date(dateRangeStart).toISOString()\n : null,\n dateRangeEnd: dateRangeEnd\n ? new Date(dateRangeEnd).toISOString()\n : null,\n });\n navigate?.(basePath);\n } catch (err) {\n setError(\n err instanceof Error\n ? err.message\n : tr(\"export.create.errors.createFailed\", \"Failed to create export\"),\n );\n }\n };\n\n const toggleEntity = (entityType: string) => {\n setSelectedEntities((prev) =>\n prev.includes(entityType)\n ? prev.filter((e) => e !== entityType)\n : [...prev, entityType],\n );\n };\n\n const getScopeLabel = (scope: ExportScope) => {\n switch (scope) {\n case \"INDIVIDUAL\":\n return tr(\"export.create.scope.individual.label\", \"My Data Only\");\n case \"WORKSPACE_ADMIN\":\n return tr(\n \"export.create.scope.workspaceAdmin.label\",\n \"All Workspace Data\",\n );\n case \"ORG_ADMIN\":\n return tr(\n \"export.create.scope.orgAdmin.label\",\n \"All Organization Data\",\n );\n default:\n return scope;\n }\n };\n\n const getScopeDescription = (scope: ExportScope) => {\n switch (scope) {\n case \"INDIVIDUAL\":\n return tr(\n \"export.create.scope.individual.description\",\n \"Export data you personally created across selected modules.\",\n );\n case \"WORKSPACE_ADMIN\":\n return tr(\n \"export.create.scope.workspaceAdmin.description\",\n \"Export all data in this workspace regardless of who created it. Requires workspace admin access.\",\n );\n case \"ORG_ADMIN\":\n return tr(\n \"export.create.scope.orgAdmin.description\",\n \"Export data from every workspace in your organization. Requires org-admin access.\",\n );\n default:\n return \"\";\n }\n };\n\n const fallbackEntityCopy: Record<\n string,\n { label: string; description: string }\n > = {\n users: {\n label: tr(\"export.create.entities.users.label\", \"Users\"),\n description: tr(\n \"export.create.entities.users.description\",\n \"Workspace members and profiles\",\n ),\n },\n projects: {\n label: tr(\"export.create.entities.projects.label\", \"Projects\"),\n description: tr(\n \"export.create.entities.projects.description\",\n \"Projects and their metadata\",\n ),\n },\n tasks: {\n label: tr(\"export.create.entities.tasks.label\", \"Tasks\"),\n description: tr(\n \"export.create.entities.tasks.description\",\n \"Task items and assignments\",\n ),\n },\n files: {\n label: tr(\"export.create.entities.files.label\", \"Files\"),\n description: tr(\n \"export.create.entities.files.description\",\n \"File metadata and references\",\n ),\n },\n conversations: {\n label: tr(\"export.create.entities.conversations.label\", \"Conversations\"),\n description: tr(\n \"export.create.entities.conversations.description\",\n \"Chat messages and threads\",\n ),\n },\n tags: {\n label: tr(\"export.create.entities.tags.label\", \"Tags\"),\n description: tr(\n \"export.create.entities.tags.description\",\n \"Tags and vocabularies\",\n ),\n },\n activity: {\n label: tr(\"export.create.entities.activity.label\", \"Activity Logs\"),\n description: tr(\n \"export.create.entities.activity.description\",\n \"Audit trail and activity history\",\n ),\n },\n calendar: {\n label: tr(\"export.create.entities.calendar.label\", \"Calendar Events\"),\n description: tr(\n \"export.create.entities.calendar.description\",\n \"Events and bookings\",\n ),\n },\n };\n\n // Only show enabled entities\n const enabledEntities = availableEntities.filter((e) => e.enabled !== false);\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={() => navigate?.(basePath)}\n className=\"p-2.5 hover:bg-accent rounded-lg transition-all duration-200 hover:scale-110\"\n aria-label={tr(\n \"export.create.actions.backToDashboard\",\n \"Back to export dashboard\",\n )}\n >\n <ArrowLeft size={20} />\n </button>\n <div className=\"flex items-center gap-3\">\n <div className=\"p-2.5 rounded-lg bg-primary/10 backdrop-blur-sm\">\n <Download size={24} className=\"text-primary\" />\n </div>\n <h1 className=\"text-2xl sm:text-3xl font-bold\">\n {tr(\"export.create.title\", \"New Export\")}\n </h1>\n </div>\n </div>\n </div>\n\n {/* Step Indicator */}\n <div className=\"flex items-center gap-2 justify-center flex-wrap\">\n {([\"entities\", \"options\", \"review\"] as WizardStep[]).map((s, i) => (\n <div key={s} className=\"flex items-center gap-2\">\n {i > 0 && (\n <ArrowRight size={18} className=\"text-muted-foreground\" />\n )}\n <div\n className={cn(\n \"flex items-center gap-2 px-4 py-2.5 rounded-lg text-sm font-medium border-2 transition-all duration-200\",\n step === s\n ? \"bg-primary text-primary-foreground border-primary shadow-md scale-105\"\n : \"bg-muted/50 text-muted-foreground border-border/50\",\n )}\n >\n <div className=\"flex items-center justify-center w-6 h-6 rounded-full bg-background/20 font-bold\">\n {i + 1}\n </div>\n <span className=\"hidden sm:inline capitalize\">\n {s === \"entities\"\n ? tr(\"export.create.steps.entities\", \"Select Data\")\n : s === \"options\"\n ? tr(\"export.create.steps.options\", \"Options\")\n : tr(\"export.create.steps.review\", \"Review\")}\n </span>\n </div>\n </div>\n ))}\n </div>\n\n {/* Error */}\n {error && (\n <div className=\"border-2 border-border-default rounded-xl bg-status-error-bg-subtle p-4 text-status-error-text text-sm\">\n {error}\n </div>\n )}\n\n {/* Step 1: Select Entities */}\n {step === \"entities\" && (\n <div className=\"space-y-4\">\n <h2 className=\"text-lg font-bold\">\n {tr(\"export.create.select.title\", \"Select data to export\")}\n </h2>\n <p className=\"text-sm text-muted-foreground\">\n {tr(\n \"export.create.select.description\",\n \"Choose which entity types to include in your export.\",\n )}\n </p>\n {enabledEntities.length === 0 ? (\n <div className=\"border-2 border-border rounded-xl bg-muted/30 p-6 text-sm text-muted-foreground\">\n {tr(\n \"export.create.select.empty\",\n \"No exportable entity types are configured for this workspace yet.\",\n )}\n </div>\n ) : (\n <div className=\"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-3\">\n {enabledEntities.map((entity) => {\n const isSelected = selectedEntities.includes(entity.entityType);\n return (\n <button\n key={entity.entityType}\n onClick={() => toggleEntity(entity.entityType)}\n className={cn(\n \"text-left border-2 rounded-xl p-4 transition-all duration-200\",\n isSelected\n ? \"border-primary bg-primary/5 shadow-md\"\n : \"border-border/50 hover:border-primary/30 hover:shadow-sm\",\n )}\n >\n <div className=\"flex items-center justify-between mb-2\">\n <h3 className=\"font-semibold\">\n {fallbackEntityCopy[entity.entityType]?.label ??\n entity.displayName}\n </h3>\n {isSelected && (\n <CheckCircle2 size={18} className=\"text-primary\" />\n )}\n </div>\n <p className=\"text-sm text-muted-foreground\">\n {fallbackEntityCopy[entity.entityType]?.description ??\n entity.description}\n </p>\n {entity.estimatedSize && (\n <p className=\"text-xs text-muted-foreground mt-2\">\n ~{entity.estimatedSize}\n </p>\n )}\n </button>\n );\n })}\n </div>\n )}\n </div>\n )}\n\n {/* Step 2: Configure Options */}\n {step === \"options\" && (\n <div className=\"space-y-6\">\n <div className=\"border-2 border-border/50 rounded-xl p-6 space-y-5\">\n <h2 className=\"text-lg font-bold\">\n {tr(\"export.create.options.title\", \"Export Options\")}\n </h2>\n\n {/* Scope selection */}\n <div>\n <label className=\"block text-sm font-semibold mb-2\">\n {tr(\"export.create.options.scope\", \"Export Scope\")}\n </label>\n <div className=\"grid grid-cols-1 sm:grid-cols-3 gap-3\">\n {SCOPE_OPTIONS.map(({ value, Icon }) => (\n <button\n key={value}\n type=\"button\"\n onClick={() => setSelectedScope(value)}\n className={cn(\n \"text-left border-2 rounded-xl p-4 transition-all duration-200\",\n selectedScope === value\n ? \"border-primary bg-primary/5 shadow-md\"\n : \"border-border/50 hover:border-primary/30 hover:shadow-sm\",\n )}\n >\n <div className=\"flex items-center justify-between mb-2\">\n <Icon\n size={18}\n className={\n selectedScope === value\n ? \"text-primary\"\n : \"text-muted-foreground\"\n }\n />\n {selectedScope === value && (\n <CheckCircle2 size={16} className=\"text-primary\" />\n )}\n </div>\n <p className=\"font-semibold text-sm\">\n {getScopeLabel(value)}\n </p>\n <p className=\"text-xs text-muted-foreground mt-1\">\n {getScopeDescription(value)}\n </p>\n </button>\n ))}\n </div>\n </div>\n\n {/* Name */}\n <div>\n <label\n htmlFor=\"exportName\"\n className=\"block text-sm font-semibold mb-2\"\n >\n {tr(\"export.create.options.name\", \"Export Name\")}{\" \"}\n <span className=\"text-status-error-text\">*</span>\n </label>\n <input\n type=\"text\"\n id=\"exportName\"\n value={exportName}\n onChange={(e) => setExportName(e.target.value)}\n className=\"w-full px-4 py-2.5 border-2 border-border rounded-lg bg-background focus:outline-none focus:ring-2 focus:ring-primary/20 focus:border-primary transition-all duration-200\"\n placeholder={tr(\n \"export.create.options.namePlaceholder\",\n \"e.g., Monthly User Export\",\n )}\n />\n </div>\n\n {/* Format — only CSV and JSON are supported */}\n <div>\n <label className=\"block text-sm font-semibold mb-2\">\n {tr(\"export.create.options.outputFormat\", \"Output Format\")}\n </label>\n <div className=\"grid grid-cols-2 gap-3\">\n {SUPPORTED_FORMATS.map((format) => {\n const Icon = FORMAT_ICONS[format];\n return (\n <button\n key={format}\n onClick={() => setSelectedFormat(format)}\n className={cn(\n \"flex items-center gap-3 border-2 rounded-lg p-3 transition-all duration-200\",\n selectedFormat === format\n ? \"border-primary bg-primary/5\"\n : \"border-border/50 hover:border-primary/30\",\n )}\n >\n <Icon\n size={18}\n className={\n selectedFormat === format\n ? \"text-primary\"\n : \"text-muted-foreground\"\n }\n />\n <span className=\"font-medium text-sm\">\n {getFormatDisplayName(format)}\n </span>\n </button>\n );\n })}\n </div>\n </div>\n\n {/* Archive format — only ZIP is supported */}\n <div>\n <label className=\"block text-sm font-semibold mb-2\">\n {tr(\"export.create.options.archiveFormat\", \"Archive Format\")}\n </label>\n <div className=\"flex gap-3\">\n <div\n className={cn(\n \"flex items-center gap-2 border-2 rounded-lg px-4 py-2 border-primary bg-primary/5\",\n )}\n >\n <Package size={16} className=\"text-primary\" />\n <span className=\"font-medium text-sm\">ZIP</span>\n </div>\n </div>\n <p className=\"text-xs text-muted-foreground mt-1.5\">\n {tr(\n \"export.create.options.archiveDescription\",\n \"Exports are packaged as ZIP archives.\",\n )}\n </p>\n </div>\n\n {/* Date range filter — always visible */}\n <div>\n <label className=\"block text-sm font-semibold mb-2\">\n <span className=\"inline-flex items-center gap-1.5\">\n <CalendarRange size={15} />\n {tr(\"export.create.options.dateRange\", \"Date Range\")}{\" \"}\n <span className=\"font-normal text-muted-foreground\">\n {tr(\"export.create.shared.optional\", \"(optional)\")}\n </span>\n </span>\n </label>\n <div className=\"grid grid-cols-1 sm:grid-cols-2 gap-3\">\n <div>\n <label\n htmlFor=\"dateFrom\"\n className=\"block text-xs text-muted-foreground mb-1\"\n >\n {tr(\"export.create.options.dateFrom\", \"From\")}\n </label>\n <input\n type=\"date\"\n id=\"dateFrom\"\n value={dateRangeStart}\n onChange={(e) => setDateRangeStart(e.target.value)}\n className=\"w-full px-3 py-2 border-2 border-border rounded-lg bg-background focus:outline-none focus:ring-2 focus:ring-primary/20 focus:border-primary text-sm\"\n />\n </div>\n <div>\n <label\n htmlFor=\"dateTo\"\n className=\"block text-xs text-muted-foreground mb-1\"\n >\n {tr(\"export.create.options.dateTo\", \"To\")}\n </label>\n <input\n type=\"date\"\n id=\"dateTo\"\n value={dateRangeEnd}\n min={dateRangeStart}\n onChange={(e) => setDateRangeEnd(e.target.value)}\n className=\"w-full px-3 py-2 border-2 border-border rounded-lg bg-background focus:outline-none focus:ring-2 focus:ring-primary/20 focus:border-primary text-sm\"\n />\n </div>\n </div>\n <p className=\"text-xs text-muted-foreground mt-1.5\">\n {tr(\n \"export.create.options.dateRangeDescription\",\n \"Leave blank to export all data regardless of date.\",\n )}\n </p>\n </div>\n\n {/* Optional: Use a template */}\n <div>\n <label className=\"block text-sm font-semibold mb-2\">\n {tr(\n \"export.create.options.basedOnTemplate\",\n \"Based on Template\",\n )}{\" \"}\n <span className=\"font-normal text-muted-foreground\">\n {tr(\"export.create.shared.optional\", \"(optional)\")}\n </span>\n </label>\n {templates.length > 0 ? (\n <select\n value={selectedTemplateId ?? \"\"}\n onChange={(e) =>\n setSelectedTemplateId(e.target.value || undefined)\n }\n className=\"w-full px-3 py-2 border-2 border-border rounded-lg bg-background focus:outline-none focus:ring-2 focus:ring-primary/20 focus:border-primary\"\n >\n <option value=\"\">\n {tr(\"export.create.options.noTemplate\", \"No template\")}\n </option>\n {templates.map((t) => (\n <option key={t.id} value={t.id}>\n {t.name}\n </option>\n ))}\n </select>\n ) : (\n <p className=\"text-sm text-muted-foreground\">\n {tr(\"export.create.options.noTemplates\", \"No templates yet.\")}{\" \"}\n <button\n type=\"button\"\n onClick={() => navigate?.(basePath + \"/templates\")}\n className=\"text-primary underline-offset-2 hover:underline\"\n >\n {tr(\n \"export.create.options.createTemplateLink\",\n \"Create one\",\n )}\n </button>{\" \"}\n {tr(\n \"export.create.options.reuseTemplateHint\",\n \"to reuse export configurations.\",\n )}\n </p>\n )}\n </div>\n </div>\n </div>\n )}\n\n {/* Step 3: Review */}\n {step === \"review\" && (\n <div className=\"space-y-6\">\n <div className=\"border-2 border-primary/50 rounded-xl bg-primary/5 p-6 space-y-4\">\n <h2 className=\"text-lg font-bold flex items-center gap-2\">\n <CheckCircle2 size={20} className=\"text-primary\" />\n {tr(\"export.create.review.title\", \"Review Export\")}\n </h2>\n <dl className=\"space-y-3 text-sm\">\n {[\n {\n label: tr(\"export.create.review.fields.name\", \"Name\"),\n value: exportName,\n },\n {\n label: tr(\"export.create.review.fields.scope\", \"Scope\"),\n value: getScopeLabel(selectedScope),\n },\n {\n label: tr(\n \"export.create.review.fields.entityTypes\",\n \"Entity Types\",\n ),\n value: selectedEntities.join(\", \"),\n },\n {\n label: tr(\"export.create.review.fields.format\", \"Format\"),\n value: getFormatDisplayName(selectedFormat),\n },\n {\n label: tr(\"export.create.review.fields.archive\", \"Archive\"),\n value: \"ZIP\",\n },\n ...(dateRangeStart || dateRangeEnd\n ? [\n {\n label: tr(\n \"export.create.review.fields.dateRange\",\n \"Date Range\",\n ),\n value: [\n dateRangeStart || \"—\",\n dateRangeEnd || \"—\",\n ].join(\" → \"),\n },\n ]\n : []),\n ...(selectedTemplateId\n ? [\n {\n label: tr(\n \"export.create.review.fields.template\",\n \"Template\",\n ),\n value:\n templates.find((t) => t.id === selectedTemplateId)\n ?.name ?? selectedTemplateId,\n },\n ]\n : []),\n ].map(({ label, value }) => (\n <div\n key={label}\n className=\"flex flex-col sm:flex-row sm:justify-between gap-1\"\n >\n <dt className=\"text-muted-foreground\">{label}</dt>\n <dd className=\"font-semibold sm:text-right break-words\">\n {value}\n </dd>\n </div>\n ))}\n </dl>\n </div>\n </div>\n )}\n\n {/* Actions */}\n <div className=\"flex flex-col sm:flex-row gap-3 pt-2\">\n <button\n onClick={handleBack}\n className=\"px-6 py-3 border-2 border-border/50 rounded-lg hover:bg-accent hover:border-primary/30 transition-all duration-200 font-medium\"\n >\n {step === \"entities\"\n ? tr(\"export.create.actions.cancel\", \"Cancel\")\n : tr(\"export.create.actions.back\", \"Back\")}\n </button>\n {step === \"review\" ? (\n <button\n onClick={handleSubmit}\n disabled={isPending}\n className=\"flex-1 inline-flex items-center justify-center gap-2 px-6 py-3 bg-primary text-primary-foreground rounded-lg hover:bg-primary/90 transition-all duration-200 hover:scale-105 font-bold shadow-lg disabled:opacity-50 disabled:cursor-not-allowed\"\n >\n {isPending ? (\n <Loader2 size={18} className=\"animate-spin\" />\n ) : (\n <Download size={18} />\n )}\n {tr(\"export.create.actions.startExport\", \"Start Export\")}\n </button>\n ) : (\n <button\n onClick={handleNext}\n className=\"flex-1 inline-flex items-center justify-center gap-2 px-6 py-3 bg-primary text-primary-foreground rounded-lg hover:bg-primary/90 transition-all duration-200 hover:scale-105 font-bold shadow-lg\"\n >\n {tr(\"export.create.actions.next\", \"Next\")}\n <ArrowRight size={18} />\n </button>\n )}\n </div>\n </PageLayout>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"CreateExportPage.js","names":[],"sources":["../../../src/export/pages/CreateExportPage.tsx"],"sourcesContent":["import { useState, useEffect, useRef } from \"react\";\nimport { useSearchParams } from \"react-router-dom\";\nimport {\n ArrowLeft,\n ArrowRight,\n Download,\n CheckCircle2,\n Loader2,\n FileSpreadsheet,\n FileJson,\n Package,\n CalendarRange,\n User,\n Users,\n Building2,\n Lock,\n} from \"lucide-react\";\nimport { useI18n } from \"@burdenoff/fe-libs/shared/providers/shell/I18nProvider\";\nimport { usePermission } from \"@burdenoff/fe-libs/shared/providers/shell\";\nimport { useExport } from \"../providers/ExportProvider\";\nimport {\n useCreateExportJob,\n useAvailableEntities,\n useExportTemplates,\n} from \"../hooks/useExportQueries\";\nimport { getFormatDisplayName } from \"../constants/enums\";\nimport { PageLayout } from \"../components/PageLayout\";\nimport { cn } from \"../utils/cn\";\nimport type { ExportFormat, ExportScope } from \"../types\";\nimport { tWithFallback } from \"../utils/i18n\";\n\ntype WizardStep = \"entities\" | \"options\" | \"review\";\n\n// Backend only supports CSV and JSON\nconst SUPPORTED_FORMATS: ExportFormat[] = [\"CSV\", \"JSON\"];\n\nconst FORMAT_ICONS: Record<ExportFormat, typeof FileJson> = {\n CSV: FileSpreadsheet,\n JSON: FileJson,\n};\n\n/**\n * Create Export Page\n * Multi-step form: select entities, configure options, review & start\n */\nconst SCOPE_OPTIONS: Array<{\n value: ExportScope;\n label: string;\n description: string;\n Icon: typeof User;\n}> = [\n {\n value: \"INDIVIDUAL\",\n label: \"My Data Only\",\n description: \"Export data you personally created across selected modules.\",\n Icon: User,\n },\n {\n value: \"WORKSPACE_ADMIN\",\n label: \"All Workspace Data\",\n description:\n \"Export all data in this workspace regardless of who created it. Requires workspace admin access.\",\n Icon: Users,\n },\n {\n value: \"ORG_ADMIN\",\n label: \"All Organization Data\",\n description:\n \"Export data from every workspace in your organization. Requires org-admin access.\",\n Icon: Building2,\n },\n];\n\nexport function CreateExportPage() {\n const { basePath = \"/\", navigate, organizationId } = 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 { createJob, isPending } = useCreateExportJob();\n const { data: availableEntities } = useAvailableEntities();\n const { data: templates } = useExportTemplates();\n const [searchParams] = useSearchParams();\n\n // RBAC: Check permissions for admin scopes\n const canExportWorkspaceAdmin = usePermission(\"export:workspace:admin\");\n const canExportOrgAdmin = usePermission(\"export:org:admin\");\n\n const [step, setStep] = useState<WizardStep>(\"entities\");\n const [selectedEntities, setSelectedEntities] = useState<string[]>([]);\n const [exportName, setExportName] = useState(\"\");\n const [selectedFormat, setSelectedFormat] = useState<ExportFormat>(\"CSV\");\n const [selectedScope, setSelectedScope] = useState<ExportScope>(\"INDIVIDUAL\");\n const [selectedTemplateId, setSelectedTemplateId] = useState<\n string | undefined\n >(searchParams.get(\"templateId\") ?? undefined);\n const [dateRangeStart, setDateRangeStart] = useState(\"\");\n const [dateRangeEnd, setDateRangeEnd] = useState(\"\");\n const [error, setError] = useState<string | null>(null);\n\n // Pre-populate form when arriving from \"Use Template\" — apply only once per templateId\n const appliedTemplateRef = useRef<string | null>(null);\n useEffect(() => {\n const paramTemplateId = searchParams.get(\"templateId\");\n if (!paramTemplateId || !templates?.length) return;\n if (appliedTemplateRef.current === paramTemplateId) return;\n const tpl = templates.find((t) => t.id === paramTemplateId);\n if (!tpl) return;\n appliedTemplateRef.current = paramTemplateId;\n setSelectedTemplateId(tpl.id);\n setSelectedEntities(tpl.entityTypes ?? []);\n const normalizedFormat = tpl.format?.toUpperCase() as\n | ExportFormat\n | undefined;\n if (normalizedFormat && SUPPORTED_FORMATS.includes(normalizedFormat)) {\n setSelectedFormat(normalizedFormat);\n }\n if (tpl.name) setExportName(tpl.name);\n }, [searchParams, templates]);\n\n const handleBack = () => {\n if (step === \"options\") setStep(\"entities\");\n else if (step === \"review\") setStep(\"options\");\n else navigate?.(basePath);\n };\n\n const handleNext = () => {\n if (step === \"entities\") {\n if (selectedEntities.length === 0) {\n setError(\n tr(\n \"export.create.errors.selectEntity\",\n \"Please select at least one entity type to export\",\n ),\n );\n return;\n }\n setError(null);\n setStep(\"options\");\n } else if (step === \"options\") {\n if (!exportName.trim()) {\n setError(\n tr(\n \"export.create.errors.exportNameRequired\",\n \"Please provide a name for this export\",\n ),\n );\n return;\n }\n setError(null);\n setStep(\"review\");\n }\n };\n\n const handleSubmit = async () => {\n try {\n setError(null);\n await createJob({\n name: exportName,\n entityTypes: selectedEntities,\n format: selectedFormat,\n exportScope: selectedScope,\n organizationId:\n selectedScope === \"ORG_ADMIN\" ? organizationId : undefined,\n templateId: selectedTemplateId,\n dateRangeStart: dateRangeStart\n ? new Date(dateRangeStart).toISOString()\n : null,\n dateRangeEnd: dateRangeEnd\n ? new Date(dateRangeEnd).toISOString()\n : null,\n });\n navigate?.(basePath);\n } catch (err) {\n setError(\n err instanceof Error\n ? err.message\n : tr(\"export.create.errors.createFailed\", \"Failed to create export\"),\n );\n }\n };\n\n const toggleEntity = (entityType: string) => {\n setSelectedEntities((prev) =>\n prev.includes(entityType)\n ? prev.filter((e) => e !== entityType)\n : [...prev, entityType],\n );\n };\n\n const getScopeLabel = (scope: ExportScope) => {\n switch (scope) {\n case \"INDIVIDUAL\":\n return tr(\"export.create.scope.individual.label\", \"My Data Only\");\n case \"WORKSPACE_ADMIN\":\n return tr(\n \"export.create.scope.workspaceAdmin.label\",\n \"All Workspace Data\",\n );\n case \"ORG_ADMIN\":\n return tr(\n \"export.create.scope.orgAdmin.label\",\n \"All Organization Data\",\n );\n default:\n return scope;\n }\n };\n\n const getScopeDescription = (scope: ExportScope) => {\n switch (scope) {\n case \"INDIVIDUAL\":\n return tr(\n \"export.create.scope.individual.description\",\n \"Export data you personally created across selected modules.\",\n );\n case \"WORKSPACE_ADMIN\":\n return tr(\n \"export.create.scope.workspaceAdmin.description\",\n \"Export all data in this workspace regardless of who created it. Requires workspace admin access.\",\n );\n case \"ORG_ADMIN\":\n return tr(\n \"export.create.scope.orgAdmin.description\",\n \"Export data from every workspace in your organization. Requires org-admin access.\",\n );\n default:\n return \"\";\n }\n };\n\n const fallbackEntityCopy: Record<\n string,\n { label: string; description: string }\n > = {\n users: {\n label: tr(\"export.create.entities.users.label\", \"Users\"),\n description: tr(\n \"export.create.entities.users.description\",\n \"Workspace members and profiles\",\n ),\n },\n projects: {\n label: tr(\"export.create.entities.projects.label\", \"Projects\"),\n description: tr(\n \"export.create.entities.projects.description\",\n \"Projects and their metadata\",\n ),\n },\n tasks: {\n label: tr(\"export.create.entities.tasks.label\", \"Tasks\"),\n description: tr(\n \"export.create.entities.tasks.description\",\n \"Task items and assignments\",\n ),\n },\n files: {\n label: tr(\"export.create.entities.files.label\", \"Files\"),\n description: tr(\n \"export.create.entities.files.description\",\n \"File metadata and references\",\n ),\n },\n conversations: {\n label: tr(\"export.create.entities.conversations.label\", \"Conversations\"),\n description: tr(\n \"export.create.entities.conversations.description\",\n \"Chat messages and threads\",\n ),\n },\n tags: {\n label: tr(\"export.create.entities.tags.label\", \"Tags\"),\n description: tr(\n \"export.create.entities.tags.description\",\n \"Tags and vocabularies\",\n ),\n },\n activity: {\n label: tr(\"export.create.entities.activity.label\", \"Activity Logs\"),\n description: tr(\n \"export.create.entities.activity.description\",\n \"Audit trail and activity history\",\n ),\n },\n calendar: {\n label: tr(\"export.create.entities.calendar.label\", \"Calendar Events\"),\n description: tr(\n \"export.create.entities.calendar.description\",\n \"Events and bookings\",\n ),\n },\n };\n\n // Only show enabled entities\n const enabledEntities = availableEntities.filter((e) => e.enabled !== false);\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={() => navigate?.(basePath)}\n className=\"p-2.5 hover:bg-accent rounded-lg transition-all duration-200 hover:scale-110\"\n aria-label={tr(\n \"export.create.actions.backToDashboard\",\n \"Back to export dashboard\",\n )}\n >\n <ArrowLeft size={20} />\n </button>\n <div className=\"flex items-center gap-3\">\n <div className=\"p-2.5 rounded-lg bg-primary/10 backdrop-blur-sm\">\n <Download size={24} className=\"text-primary\" />\n </div>\n <h1 className=\"text-2xl sm:text-3xl font-bold\">\n {tr(\"export.create.title\", \"New Export\")}\n </h1>\n </div>\n </div>\n </div>\n\n {/* Step Indicator */}\n <div className=\"flex items-center gap-2 justify-center flex-wrap\">\n {([\"entities\", \"options\", \"review\"] as WizardStep[]).map((s, i) => (\n <div key={s} className=\"flex items-center gap-2\">\n {i > 0 && (\n <ArrowRight size={18} className=\"text-muted-foreground\" />\n )}\n <div\n className={cn(\n \"flex items-center gap-2 px-4 py-2.5 rounded-lg text-sm font-medium border-2 transition-all duration-200\",\n step === s\n ? \"bg-primary text-primary-foreground border-primary shadow-md scale-105\"\n : \"bg-muted/50 text-muted-foreground border-border/50\",\n )}\n >\n <div className=\"flex items-center justify-center w-6 h-6 rounded-full bg-background/20 font-bold\">\n {i + 1}\n </div>\n <span className=\"hidden sm:inline capitalize\">\n {s === \"entities\"\n ? tr(\"export.create.steps.entities\", \"Select Data\")\n : s === \"options\"\n ? tr(\"export.create.steps.options\", \"Options\")\n : tr(\"export.create.steps.review\", \"Review\")}\n </span>\n </div>\n </div>\n ))}\n </div>\n\n {/* Error */}\n {error && (\n <div className=\"border-2 border-border-default rounded-xl bg-status-error-bg-subtle p-4 text-status-error-text text-sm\">\n {error}\n </div>\n )}\n\n {/* Step 1: Select Entities */}\n {step === \"entities\" && (\n <div className=\"space-y-4\">\n <h2 className=\"text-lg font-bold\">\n {tr(\"export.create.select.title\", \"Select data to export\")}\n </h2>\n <p className=\"text-sm text-muted-foreground\">\n {tr(\n \"export.create.select.description\",\n \"Choose which entity types to include in your export.\",\n )}\n </p>\n {enabledEntities.length === 0 ? (\n <div className=\"border-2 border-border rounded-xl bg-muted/30 p-6 text-sm text-muted-foreground\">\n {tr(\n \"export.create.select.empty\",\n \"No exportable entity types are configured for this workspace yet.\",\n )}\n </div>\n ) : (\n <div className=\"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-3\">\n {enabledEntities.map((entity) => {\n const isSelected = selectedEntities.includes(entity.entityType);\n return (\n <button\n key={entity.entityType}\n onClick={() => toggleEntity(entity.entityType)}\n className={cn(\n \"text-left border-2 rounded-xl p-4 transition-all duration-200\",\n isSelected\n ? \"border-primary bg-primary/5 shadow-md\"\n : \"border-border/50 hover:border-primary/30 hover:shadow-sm\",\n )}\n >\n <div className=\"flex items-center justify-between mb-2\">\n <h3 className=\"font-semibold\">\n {fallbackEntityCopy[entity.entityType]?.label ??\n entity.displayName}\n </h3>\n {isSelected && (\n <CheckCircle2 size={18} className=\"text-primary\" />\n )}\n </div>\n <p className=\"text-sm text-muted-foreground\">\n {fallbackEntityCopy[entity.entityType]?.description ??\n entity.description}\n </p>\n {entity.estimatedSize && (\n <p className=\"text-xs text-muted-foreground mt-2\">\n ~{entity.estimatedSize}\n </p>\n )}\n </button>\n );\n })}\n </div>\n )}\n </div>\n )}\n\n {/* Step 2: Configure Options */}\n {step === \"options\" && (\n <div className=\"space-y-6\">\n <div className=\"border-2 border-border/50 rounded-xl p-6 space-y-5\">\n <h2 className=\"text-lg font-bold\">\n {tr(\"export.create.options.title\", \"Export Options\")}\n </h2>\n\n {/* Scope selection */}\n <div>\n <label className=\"block text-sm font-semibold mb-2\">\n {tr(\"export.create.options.scope\", \"Export Scope\")}\n </label>\n <div className=\"grid grid-cols-1 sm:grid-cols-3 gap-3\">\n {SCOPE_OPTIONS.map(({ value, Icon }) => {\n // RBAC: Disable admin scopes if user lacks permission\n const isDisabled =\n (value === \"WORKSPACE_ADMIN\" && !canExportWorkspaceAdmin) ||\n (value === \"ORG_ADMIN\" && !canExportOrgAdmin);\n\n return (\n <button\n key={value}\n type=\"button\"\n onClick={() => !isDisabled && setSelectedScope(value)}\n disabled={isDisabled}\n className={cn(\n \"text-left border-2 rounded-xl p-4 transition-all duration-200\",\n selectedScope === value\n ? \"border-primary bg-primary/5 shadow-md\"\n : isDisabled\n ? \"border-border/30 opacity-50 cursor-not-allowed\"\n : \"border-border/50 hover:border-primary/30 hover:shadow-sm\",\n )}\n title={\n isDisabled\n ? value === \"WORKSPACE_ADMIN\"\n ? \"Workspace admin access required\"\n : \"Organization admin access required\"\n : undefined\n }\n >\n <div className=\"flex items-center justify-between mb-2\">\n <Icon\n size={18}\n className={\n selectedScope === value\n ? \"text-primary\"\n : isDisabled\n ? \"text-muted-foreground/50\"\n : \"text-muted-foreground\"\n }\n />\n {selectedScope === value && (\n <CheckCircle2 size={16} className=\"text-primary\" />\n )}\n {isDisabled && (\n <Lock\n size={14}\n className=\"text-muted-foreground/50\"\n />\n )}\n </div>\n <p className=\"font-semibold text-sm\">\n {getScopeLabel(value)}\n </p>\n <p className=\"text-xs text-muted-foreground mt-1\">\n {getScopeDescription(value)}\n </p>\n </button>\n );\n })}\n </div>\n </div>\n\n {/* Name */}\n <div>\n <label\n htmlFor=\"exportName\"\n className=\"block text-sm font-semibold mb-2\"\n >\n {tr(\"export.create.options.name\", \"Export Name\")}{\" \"}\n <span className=\"text-status-error-text\">*</span>\n </label>\n <input\n type=\"text\"\n id=\"exportName\"\n value={exportName}\n onChange={(e) => setExportName(e.target.value)}\n className=\"w-full px-4 py-2.5 border-2 border-border rounded-lg bg-background focus:outline-none focus:ring-2 focus:ring-primary/20 focus:border-primary transition-all duration-200\"\n placeholder={tr(\n \"export.create.options.namePlaceholder\",\n \"e.g., Monthly User Export\",\n )}\n />\n </div>\n\n {/* Format — only CSV and JSON are supported */}\n <div>\n <label className=\"block text-sm font-semibold mb-2\">\n {tr(\"export.create.options.outputFormat\", \"Output Format\")}\n </label>\n <div className=\"grid grid-cols-2 gap-3\">\n {SUPPORTED_FORMATS.map((format) => {\n const Icon = FORMAT_ICONS[format];\n return (\n <button\n key={format}\n onClick={() => setSelectedFormat(format)}\n className={cn(\n \"flex items-center gap-3 border-2 rounded-lg p-3 transition-all duration-200\",\n selectedFormat === format\n ? \"border-primary bg-primary/5\"\n : \"border-border/50 hover:border-primary/30\",\n )}\n >\n <Icon\n size={18}\n className={\n selectedFormat === format\n ? \"text-primary\"\n : \"text-muted-foreground\"\n }\n />\n <span className=\"font-medium text-sm\">\n {getFormatDisplayName(format)}\n </span>\n </button>\n );\n })}\n </div>\n </div>\n\n {/* Archive format — only ZIP is supported */}\n <div>\n <label className=\"block text-sm font-semibold mb-2\">\n {tr(\"export.create.options.archiveFormat\", \"Archive Format\")}\n </label>\n <div className=\"flex gap-3\">\n <div\n className={cn(\n \"flex items-center gap-2 border-2 rounded-lg px-4 py-2 border-primary bg-primary/5\",\n )}\n >\n <Package size={16} className=\"text-primary\" />\n <span className=\"font-medium text-sm\">ZIP</span>\n </div>\n </div>\n <p className=\"text-xs text-muted-foreground mt-1.5\">\n {tr(\n \"export.create.options.archiveDescription\",\n \"Exports are packaged as ZIP archives.\",\n )}\n </p>\n </div>\n\n {/* Date range filter — always visible */}\n <div>\n <label className=\"block text-sm font-semibold mb-2\">\n <span className=\"inline-flex items-center gap-1.5\">\n <CalendarRange size={15} />\n {tr(\"export.create.options.dateRange\", \"Date Range\")}{\" \"}\n <span className=\"font-normal text-muted-foreground\">\n {tr(\"export.create.shared.optional\", \"(optional)\")}\n </span>\n </span>\n </label>\n <div className=\"grid grid-cols-1 sm:grid-cols-2 gap-3\">\n <div>\n <label\n htmlFor=\"dateFrom\"\n className=\"block text-xs text-muted-foreground mb-1\"\n >\n {tr(\"export.create.options.dateFrom\", \"From\")}\n </label>\n <input\n type=\"date\"\n id=\"dateFrom\"\n value={dateRangeStart}\n onChange={(e) => setDateRangeStart(e.target.value)}\n className=\"w-full px-3 py-2 border-2 border-border rounded-lg bg-background focus:outline-none focus:ring-2 focus:ring-primary/20 focus:border-primary text-sm\"\n />\n </div>\n <div>\n <label\n htmlFor=\"dateTo\"\n className=\"block text-xs text-muted-foreground mb-1\"\n >\n {tr(\"export.create.options.dateTo\", \"To\")}\n </label>\n <input\n type=\"date\"\n id=\"dateTo\"\n value={dateRangeEnd}\n min={dateRangeStart}\n onChange={(e) => setDateRangeEnd(e.target.value)}\n className=\"w-full px-3 py-2 border-2 border-border rounded-lg bg-background focus:outline-none focus:ring-2 focus:ring-primary/20 focus:border-primary text-sm\"\n />\n </div>\n </div>\n <p className=\"text-xs text-muted-foreground mt-1.5\">\n {tr(\n \"export.create.options.dateRangeDescription\",\n \"Leave blank to export all data regardless of date.\",\n )}\n </p>\n </div>\n\n {/* Optional: Use a template */}\n <div>\n <label className=\"block text-sm font-semibold mb-2\">\n {tr(\n \"export.create.options.basedOnTemplate\",\n \"Based on Template\",\n )}{\" \"}\n <span className=\"font-normal text-muted-foreground\">\n {tr(\"export.create.shared.optional\", \"(optional)\")}\n </span>\n </label>\n {templates.length > 0 ? (\n <select\n value={selectedTemplateId ?? \"\"}\n onChange={(e) =>\n setSelectedTemplateId(e.target.value || undefined)\n }\n className=\"w-full px-3 py-2 border-2 border-border rounded-lg bg-background focus:outline-none focus:ring-2 focus:ring-primary/20 focus:border-primary\"\n >\n <option value=\"\">\n {tr(\"export.create.options.noTemplate\", \"No template\")}\n </option>\n {templates.map((t) => (\n <option key={t.id} value={t.id}>\n {t.name}\n </option>\n ))}\n </select>\n ) : (\n <p className=\"text-sm text-muted-foreground\">\n {tr(\"export.create.options.noTemplates\", \"No templates yet.\")}{\" \"}\n <button\n type=\"button\"\n onClick={() => navigate?.(basePath + \"/templates\")}\n className=\"text-primary underline-offset-2 hover:underline\"\n >\n {tr(\n \"export.create.options.createTemplateLink\",\n \"Create one\",\n )}\n </button>{\" \"}\n {tr(\n \"export.create.options.reuseTemplateHint\",\n \"to reuse export configurations.\",\n )}\n </p>\n )}\n </div>\n </div>\n </div>\n )}\n\n {/* Step 3: Review */}\n {step === \"review\" && (\n <div className=\"space-y-6\">\n <div className=\"border-2 border-primary/50 rounded-xl bg-primary/5 p-6 space-y-4\">\n <h2 className=\"text-lg font-bold flex items-center gap-2\">\n <CheckCircle2 size={20} className=\"text-primary\" />\n {tr(\"export.create.review.title\", \"Review Export\")}\n </h2>\n <dl className=\"space-y-3 text-sm\">\n {[\n {\n label: tr(\"export.create.review.fields.name\", \"Name\"),\n value: exportName,\n },\n {\n label: tr(\"export.create.review.fields.scope\", \"Scope\"),\n value: getScopeLabel(selectedScope),\n },\n {\n label: tr(\n \"export.create.review.fields.entityTypes\",\n \"Entity Types\",\n ),\n value: selectedEntities.join(\", \"),\n },\n {\n label: tr(\"export.create.review.fields.format\", \"Format\"),\n value: getFormatDisplayName(selectedFormat),\n },\n {\n label: tr(\"export.create.review.fields.archive\", \"Archive\"),\n value: \"ZIP\",\n },\n ...(dateRangeStart || dateRangeEnd\n ? [\n {\n label: tr(\n \"export.create.review.fields.dateRange\",\n \"Date Range\",\n ),\n value: [\n dateRangeStart || \"—\",\n dateRangeEnd || \"—\",\n ].join(\" → \"),\n },\n ]\n : []),\n ...(selectedTemplateId\n ? [\n {\n label: tr(\n \"export.create.review.fields.template\",\n \"Template\",\n ),\n value:\n templates.find((t) => t.id === selectedTemplateId)\n ?.name ?? selectedTemplateId,\n },\n ]\n : []),\n ].map(({ label, value }) => (\n <div\n key={label}\n className=\"flex flex-col sm:flex-row sm:justify-between gap-1\"\n >\n <dt className=\"text-muted-foreground\">{label}</dt>\n <dd className=\"font-semibold sm:text-right break-words\">\n {value}\n </dd>\n </div>\n ))}\n </dl>\n </div>\n </div>\n )}\n\n {/* Actions */}\n <div className=\"flex flex-col sm:flex-row gap-3 pt-2\">\n <button\n onClick={handleBack}\n className=\"px-6 py-3 border-2 border-border/50 rounded-lg hover:bg-accent hover:border-primary/30 transition-all duration-200 font-medium\"\n >\n {step === \"entities\"\n ? tr(\"export.create.actions.cancel\", \"Cancel\")\n : tr(\"export.create.actions.back\", \"Back\")}\n </button>\n {step === \"review\" ? (\n <button\n onClick={handleSubmit}\n disabled={isPending}\n className=\"flex-1 inline-flex items-center justify-center gap-2 px-6 py-3 bg-primary text-primary-foreground rounded-lg hover:bg-primary/90 transition-all duration-200 hover:scale-105 font-bold shadow-lg disabled:opacity-50 disabled:cursor-not-allowed\"\n >\n {isPending ? (\n <Loader2 size={18} className=\"animate-spin\" />\n ) : (\n <Download size={18} />\n )}\n {tr(\"export.create.actions.startExport\", \"Start Export\")}\n </button>\n ) : (\n <button\n onClick={handleNext}\n className=\"flex-1 inline-flex items-center justify-center gap-2 px-6 py-3 bg-primary text-primary-foreground rounded-lg hover:bg-primary/90 transition-all duration-200 hover:scale-105 font-bold shadow-lg\"\n >\n {tr(\"export.create.actions.next\", \"Next\")}\n <ArrowRight size={18} />\n </button>\n )}\n </div>\n </PageLayout>\n );\n}\n"],"mappings":"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"}
|