@burdenoff/microfe-export 2026.525.2 → 2026.527.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.
Files changed (80) hide show
  1. package/dist/export/ExportRoutes.js +5 -4
  2. package/dist/export/ExportRoutes.js.map +1 -1
  3. package/dist/export/components/ExportStatusBadge.js +2 -2
  4. package/dist/export/components/ExportStatusBadge.js.map +1 -1
  5. package/dist/export/constants/enums.js +13 -13
  6. package/dist/export/constants/enums.js.map +1 -1
  7. package/dist/export/hooks/useExportQueries.js.map +1 -1
  8. package/dist/export/pages/CreateExportPage.js +10 -1
  9. package/dist/export/pages/CreateExportPage.js.map +1 -1
  10. package/dist/export/pages/ExportDashboardPage.js +5 -0
  11. package/dist/export/pages/ExportDashboardPage.js.map +1 -1
  12. package/dist/export/pages/ExportDetailPage.js +7 -1
  13. package/dist/export/pages/ExportDetailPage.js.map +1 -1
  14. package/dist/export/pages/ExportHistoryPage.js +136 -124
  15. package/dist/export/pages/ExportHistoryPage.js.map +1 -1
  16. package/dist/export/pages/ExportTemplatesPage.js +148 -136
  17. package/dist/export/pages/ExportTemplatesPage.js.map +1 -1
  18. package/dist/export/pages/TemplateDetailPage.js +6 -1
  19. package/dist/export/pages/TemplateDetailPage.js.map +1 -1
  20. package/package.json +1 -1
  21. package/dist/dev/main.d.ts +0 -2
  22. package/dist/dev/main.d.ts.map +0 -1
  23. package/dist/export/ExportRoot.d.ts +0 -31
  24. package/dist/export/ExportRoot.d.ts.map +0 -1
  25. package/dist/export/ExportRoutes.d.ts +0 -14
  26. package/dist/export/ExportRoutes.d.ts.map +0 -1
  27. package/dist/export/components/ExportProgressBar.d.ts +0 -12
  28. package/dist/export/components/ExportProgressBar.d.ts.map +0 -1
  29. package/dist/export/components/ExportStatusBadge.d.ts +0 -12
  30. package/dist/export/components/ExportStatusBadge.d.ts.map +0 -1
  31. package/dist/export/components/PageLayout.d.ts +0 -55
  32. package/dist/export/components/PageLayout.d.ts.map +0 -1
  33. package/dist/export/components/ui.d.ts +0 -6
  34. package/dist/export/components/ui.d.ts.map +0 -1
  35. package/dist/export/constants/enums.d.ts +0 -79
  36. package/dist/export/constants/enums.d.ts.map +0 -1
  37. package/dist/export/constants/index.d.ts +0 -7
  38. package/dist/export/constants/index.d.ts.map +0 -1
  39. package/dist/export/hooks/useExportQueries.d.ts +0 -224
  40. package/dist/export/hooks/useExportQueries.d.ts.map +0 -1
  41. package/dist/export/index.d.ts +0 -29
  42. package/dist/export/index.d.ts.map +0 -1
  43. package/dist/export/pages/CreateExportPage.d.ts +0 -2
  44. package/dist/export/pages/CreateExportPage.d.ts.map +0 -1
  45. package/dist/export/pages/ExportDashboardPage.d.ts +0 -6
  46. package/dist/export/pages/ExportDashboardPage.d.ts.map +0 -1
  47. package/dist/export/pages/ExportDetailPage.d.ts +0 -7
  48. package/dist/export/pages/ExportDetailPage.d.ts.map +0 -1
  49. package/dist/export/pages/ExportHistoryPage.d.ts +0 -6
  50. package/dist/export/pages/ExportHistoryPage.d.ts.map +0 -1
  51. package/dist/export/pages/ExportLandingPage.d.ts +0 -9
  52. package/dist/export/pages/ExportLandingPage.d.ts.map +0 -1
  53. package/dist/export/pages/ExportTemplatesPage.d.ts +0 -6
  54. package/dist/export/pages/ExportTemplatesPage.d.ts.map +0 -1
  55. package/dist/export/pages/TemplateDetailPage.d.ts +0 -7
  56. package/dist/export/pages/TemplateDetailPage.d.ts.map +0 -1
  57. package/dist/export/providers/ExportProvider.d.ts +0 -13
  58. package/dist/export/providers/ExportProvider.d.ts.map +0 -1
  59. package/dist/export/store/exportStore.d.ts +0 -17
  60. package/dist/export/store/exportStore.d.ts.map +0 -1
  61. package/dist/export/types/index.d.ts +0 -230
  62. package/dist/export/types/index.d.ts.map +0 -1
  63. package/dist/export/utils/cn.d.ts +0 -8
  64. package/dist/export/utils/cn.d.ts.map +0 -1
  65. package/dist/export/utils/events.d.ts +0 -7
  66. package/dist/export/utils/events.d.ts.map +0 -1
  67. package/dist/export/utils/i18n.d.ts +0 -6
  68. package/dist/export/utils/i18n.d.ts.map +0 -1
  69. package/dist/generated/global-operations.d.ts +0 -2
  70. package/dist/generated/global-operations.d.ts.map +0 -1
  71. package/dist/generated/global-types.d.ts +0 -23527
  72. package/dist/generated/global-types.d.ts.map +0 -1
  73. package/dist/generated/wspace-operations.d.ts +0 -773
  74. package/dist/generated/wspace-operations.d.ts.map +0 -1
  75. package/dist/generated/wspace-types.d.ts +0 -57851
  76. package/dist/generated/wspace-types.d.ts.map +0 -1
  77. package/dist/index.d.ts +0 -6
  78. package/dist/index.d.ts.map +0 -1
  79. package/dist/utils/nativeBridge.d.ts +0 -3
  80. package/dist/utils/nativeBridge.d.ts.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"ExportTemplatesPage.js","names":[],"sources":["../../../src/export/pages/ExportTemplatesPage.tsx"],"sourcesContent":["import { useState, useMemo } from \"react\";\nimport {\n Search,\n X,\n FileBox,\n Plus,\n ChevronRight,\n Sparkles,\n Loader2,\n} from \"lucide-react\";\nimport { useI18n } from \"@burdenoff/fe-libs/shared/providers/shell/I18nProvider\";\nimport { useExport } from \"../providers/ExportProvider\";\nimport {\n useExportTemplates,\n useDeleteExportTemplate,\n useCreateExportTemplate,\n useAvailableEntities,\n} from \"../hooks/useExportQueries\";\nimport { PageLayout, EmptyState } from \"../components/PageLayout\";\nimport { getFormatDisplayName } from \"../constants/enums\";\nimport { cn } from \"../utils/cn\";\nimport { tWithFallback } from \"../utils/i18n\";\nimport type { ExportFormat } from \"../types\";\nimport { nativeImpact, nativeNotify } from \"../../utils/nativeBridge\";\n\n/**\n * Helper to join paths correctly\n */\nconst joinPath = (base: string, path: string): string => {\n const cleanBase = base.endsWith(\"/\") ? base.slice(0, -1) : base;\n const cleanPath = path.startsWith(\"/\") ? path : `/${path}`;\n return cleanBase + cleanPath;\n};\n\n/**\n * Export Templates Page\n * Template management list for reusable export configurations\n */\nexport function ExportTemplatesPage() {\n const { basePath = \"/\", navigate } = useExport();\n const { t } = useI18n();\n const tr = (\n key: string,\n fallback: string,\n params?: Record<string, string | number>,\n ) => tWithFallback(t, key, fallback, params);\n const { data: templates, isLoading } = useExportTemplates();\n const { deleteTemplate } = useDeleteExportTemplate();\n const { createTemplate, isPending: creating } = useCreateExportTemplate();\n const { data: availableEntities } = useAvailableEntities();\n\n const [searchQuery, setSearchQuery] = useState(\"\");\n const [showCreateForm, setShowCreateForm] = useState(false);\n const [newTemplateName, setNewTemplateName] = useState(\"\");\n const [newTemplateDescription, setNewTemplateDescription] = useState(\"\");\n const [newTemplateEntityTypes, setNewTemplateEntityTypes] = useState<\n string[]\n >([]);\n const [newTemplateFormat, setNewTemplateFormat] =\n useState<ExportFormat>(\"CSV\");\n const [createError, setCreateError] = useState<string | null>(null);\n const [templatePendingDelete, setTemplatePendingDelete] = useState<\n string | null\n >(null);\n\n const handleOpenCreate = () => {\n setNewTemplateName(\"\");\n setNewTemplateDescription(\"\");\n setNewTemplateEntityTypes([]);\n setNewTemplateFormat(\"CSV\");\n setCreateError(null);\n setShowCreateForm(true);\n };\n\n const handleCreateTemplate = async () => {\n if (!newTemplateName.trim()) {\n setCreateError(\n tr(\n \"export.templates.form.errors.nameRequired\",\n \"Template name is required.\",\n ),\n );\n return;\n }\n if (newTemplateEntityTypes.length === 0) {\n setCreateError(\n tr(\n \"export.templates.form.errors.entityRequired\",\n \"Select at least one entity type.\",\n ),\n );\n return;\n }\n setCreateError(null);\n try {\n await createTemplate({\n name: newTemplateName.trim(),\n description: newTemplateDescription.trim() || undefined,\n entityTypes: newTemplateEntityTypes,\n format: newTemplateFormat,\n });\n setShowCreateForm(false);\n } catch (err) {\n setCreateError(\n err instanceof Error\n ? err.message\n : tr(\n \"export.templates.form.errors.createFailed\",\n \"Failed to create template.\",\n ),\n );\n }\n };\n\n const toggleEntity = (entityType: string) => {\n setNewTemplateEntityTypes((prev) =>\n prev.includes(entityType)\n ? prev.filter((e) => e !== entityType)\n : [...prev, entityType],\n );\n };\n\n // Client-side search filter\n const filteredTemplates = useMemo(() => {\n if (!searchQuery) return templates;\n const q = searchQuery.toLowerCase();\n return templates.filter(\n (t) =>\n t.name.toLowerCase().includes(q) ||\n t.entityTypes.some((e) => e.toLowerCase().includes(q)),\n );\n }, [templates, searchQuery]);\n\n const handleTemplateClick = (templateId: string) => {\n navigate?.(joinPath(basePath, `templates/${templateId}`));\n };\n\n const handleDeleteTemplate = async (\n e: React.MouseEvent,\n templateId: string,\n ) => {\n e.stopPropagation();\n nativeImpact(\"medium\");\n setTemplatePendingDelete(templateId);\n };\n\n const confirmDeleteTemplate = async () => {\n if (!templatePendingDelete) return;\n try {\n await deleteTemplate(templatePendingDelete);\n nativeNotify(\"success\");\n } catch {\n nativeNotify(\"error\");\n }\n setTemplatePendingDelete(null);\n };\n\n return (\n <PageLayout\n title={tr(\"export.templates.title\", \"Export Templates\")}\n subtitle={tr(\n \"export.templates.subtitle\",\n \"Reusable export configurations for common data exports\",\n )}\n icon={<FileBox size={24} />}\n headerActions={\n <div className=\"flex flex-wrap items-center gap-2\">\n <button\n onClick={handleOpenCreate}\n className=\"inline-flex items-center gap-2 px-3 py-2 sm:px-4 bg-primary text-primary-foreground rounded-lg hover:bg-primary/90 transition-colors font-medium text-sm\"\n >\n <Plus size={16} />\n {tr(\"export.templates.actions.newTemplate\", \"New Template\")}\n </button>\n <button\n onClick={() => navigate?.(joinPath(basePath, \"new\"))}\n className=\"inline-flex items-center gap-2 px-3 py-2 sm:px-4 border-2 border-border rounded-lg hover:bg-accent transition-colors font-medium text-sm\"\n >\n <Plus size={16} />\n {tr(\"export.templates.actions.newExport\", \"New Export\")}\n </button>\n </div>\n }\n headerContent={\n <span className=\"inline-flex items-center gap-1.5 px-2.5 py-0.5 rounded-full text-xs font-medium bg-muted text-muted-foreground\">\n <Sparkles size={12} />\n {tr(\n \"export.templates.summary.available\",\n \"{count} template{suffix} available\",\n {\n count: filteredTemplates.length,\n suffix: filteredTemplates.length !== 1 ? \"s\" : \"\",\n },\n )}\n </span>\n }\n >\n {/* Create Template Form */}\n {showCreateForm && (\n <div className=\"border-2 border-primary/30 rounded-xl p-6 bg-primary/5 space-y-4\">\n <div className=\"flex items-center justify-between\">\n <h3 className=\"font-semibold text-lg\">\n {tr(\"export.templates.form.title\", \"New Template\")}\n </h3>\n <button\n onClick={() => setShowCreateForm(false)}\n className=\"p-1.5 rounded-md hover:bg-accent\"\n >\n <X size={16} />\n </button>\n </div>\n {createError && (\n <p className=\"text-sm text-destructive bg-destructive/10 rounded-lg px-3 py-2\">\n {createError}\n </p>\n )}\n <div className=\"grid grid-cols-1 sm:grid-cols-2 gap-4\">\n <div className=\"space-y-1\">\n <label className=\"text-sm font-medium\">\n {tr(\"export.templates.form.fields.name\", \"Name\")} *\n </label>\n <input\n type=\"text\"\n placeholder={tr(\n \"export.templates.form.fields.namePlaceholder\",\n \"e.g. Weekly Tags Export\",\n )}\n value={newTemplateName}\n onChange={(e) => setNewTemplateName(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 transition-all\"\n />\n </div>\n <div className=\"space-y-1\">\n <label className=\"text-sm font-medium\">\n {tr(\"export.templates.form.fields.format\", \"Format\")} *\n </label>\n <select\n value={newTemplateFormat}\n onChange={(e) =>\n setNewTemplateFormat(e.target.value as ExportFormat)\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 transition-all\"\n >\n <option value=\"CSV\">CSV</option>\n <option value=\"JSON\">JSON</option>\n </select>\n </div>\n </div>\n <div className=\"space-y-1\">\n <label className=\"text-sm font-medium\">\n {tr(\"export.templates.form.fields.description\", \"Description\")}\n </label>\n <input\n type=\"text\"\n placeholder={tr(\n \"export.templates.form.fields.descriptionPlaceholder\",\n \"Optional description\",\n )}\n value={newTemplateDescription}\n onChange={(e) => setNewTemplateDescription(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 transition-all\"\n />\n </div>\n <div className=\"space-y-2\">\n <label className=\"text-sm font-medium\">\n {tr(\"export.templates.form.fields.entityTypes\", \"Entity Types\")} *{\" \"}\n <span className=\"text-muted-foreground font-normal\">\n {tr(\n \"export.templates.form.fields.entityTypesHint\",\n \"(select at least one)\",\n )}\n </span>\n </label>\n <div className=\"flex flex-wrap gap-2\">\n {availableEntities.map((entity) => (\n <button\n key={entity.entityType}\n type=\"button\"\n onClick={() => toggleEntity(entity.entityType)}\n className={cn(\n \"px-3 py-1.5 rounded-lg text-sm font-medium border-2 transition-all\",\n newTemplateEntityTypes.includes(entity.entityType)\n ? \"border-primary bg-primary/10 text-primary\"\n : \"border-border bg-background hover:border-primary/50\",\n )}\n >\n {entity.displayName}\n </button>\n ))}\n </div>\n </div>\n <div className=\"flex gap-3 pt-2\">\n <button\n onClick={handleCreateTemplate}\n disabled={creating}\n className=\"inline-flex items-center gap-2 px-5 py-2.5 bg-primary text-primary-foreground rounded-lg hover:bg-primary/90 transition-colors font-medium disabled:opacity-50\"\n >\n {creating ? (\n <Loader2 size={16} className=\"animate-spin\" />\n ) : (\n <Plus size={16} />\n )}\n {tr(\"export.templates.form.actions.create\", \"Create Template\")}\n </button>\n <button\n onClick={() => setShowCreateForm(false)}\n className=\"px-5 py-2.5 border-2 border-border rounded-lg hover:bg-accent transition-colors font-medium\"\n >\n {tr(\"export.templates.form.actions.cancel\", \"Cancel\")}\n </button>\n </div>\n </div>\n )}\n {/* Search */}\n <div className=\"relative group\">\n <Search\n size={18}\n className=\"absolute left-3 top-1/2 -translate-y-1/2 text-muted-foreground group-focus-within:text-primary transition-colors\"\n />\n <input\n type=\"text\"\n placeholder={tr(\n \"export.templates.search.placeholder\",\n \"Search templates...\",\n )}\n value={searchQuery}\n onChange={(e) => setSearchQuery(e.target.value)}\n className=\"w-full pl-[3.25rem] pr-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 />\n {searchQuery && (\n <button\n onClick={() => setSearchQuery(\"\")}\n className=\"absolute right-3 top-1/2 -translate-y-1/2 p-1 rounded-md text-muted-foreground hover:text-foreground hover:bg-accent\"\n >\n <X size={16} />\n </button>\n )}\n </div>\n\n {/* Loading */}\n {isLoading && (\n <div className=\"grid grid-cols-1 lg:grid-cols-2 gap-4\">\n {[...Array(4)].map((_, i) => (\n <div\n key={i}\n className=\"border-2 border-border/50 rounded-xl p-5 animate-pulse\"\n >\n <div className=\"h-5 w-40 bg-muted rounded mb-3\" />\n <div className=\"h-3 w-full bg-muted rounded mb-2\" />\n <div className=\"flex gap-2 mt-4\">\n <div className=\"h-5 w-16 bg-muted rounded-full\" />\n <div className=\"h-5 w-16 bg-muted rounded-full\" />\n </div>\n </div>\n ))}\n </div>\n )}\n\n {/* Templates Grid */}\n {!isLoading ? (\n filteredTemplates.length > 0 ? (\n <div className=\"grid grid-cols-1 lg:grid-cols-2 gap-4\">\n {filteredTemplates.map((template, index) => (\n <div\n key={template.id}\n role=\"button\"\n tabIndex={0}\n onClick={() => handleTemplateClick(template.id)}\n onKeyDown={(e) => {\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n handleTemplateClick(template.id);\n }\n }}\n className={cn(\n \"text-left group cursor-pointer border-2 border-border/50 rounded-xl overflow-hidden\",\n \"hover:shadow-md hover:border-primary/30 transition-all duration-200\",\n \"animate-in fade-in-0 slide-in-from-bottom-2\",\n )}\n style={{ animationDelay: `${index * 50}ms` }}\n >\n {/* Header */}\n <div className=\"p-4 border-b bg-muted/30\">\n <div className=\"flex items-start justify-between\">\n <div className=\"flex items-center gap-3\">\n <div className=\"p-2 rounded-lg bg-primary/10\">\n <FileBox size={20} className=\"text-primary\" />\n </div>\n <div>\n <h3 className=\"font-semibold\">{template.name}</h3>\n <p className=\"text-xs text-muted-foreground\">\n {getFormatDisplayName(template.format)}\n {template.isDefault && (\n <span className=\"ml-1.5 inline-flex items-center px-1.5 py-0.5 rounded text-xs bg-primary/10 text-primary font-medium\">\n {tr(\"export.templates.card.default\", \"Default\")}\n </span>\n )}\n </p>\n </div>\n </div>\n <div className=\"flex items-center gap-2\">\n <button\n onClick={(e) => handleDeleteTemplate(e, template.id)}\n className=\"p-1.5 rounded-md text-muted-foreground hover:text-destructive hover:bg-destructive/10 transition-colors\"\n aria-label={tr(\n \"export.templates.card.deleteAriaLabel\",\n \"Delete {name}\",\n { name: template.name },\n )}\n >\n <X size={14} />\n </button>\n <ChevronRight\n size={18}\n className=\"text-muted-foreground group-hover:text-primary transition-colors mt-1\"\n />\n </div>\n </div>\n </div>\n\n {/* Body */}\n <div className=\"p-4\">\n {template.description && (\n <p className=\"text-sm text-muted-foreground mb-3 line-clamp-2\">\n {template.description}\n </p>\n )}\n <div className=\"flex flex-wrap gap-1.5 overflow-hidden\">\n {template.entityTypes.slice(0, 6).map((entity) => (\n <span\n key={entity}\n className=\"inline-flex px-2 py-0.5 rounded text-xs font-medium bg-muted text-muted-foreground max-w-full truncate\"\n >\n {entity}\n </span>\n ))}\n {template.entityTypes.length > 6 && (\n <span className=\"inline-flex px-2 py-0.5 rounded text-xs font-medium bg-muted text-muted-foreground\">\n {tr(\n \"export.templates.card.moreEntities\",\n \"+{count} more\",\n {\n count: template.entityTypes.length - 6,\n },\n )}\n </span>\n )}\n </div>\n </div>\n </div>\n ))}\n </div>\n ) : (\n <EmptyState\n icon={searchQuery ? <Search size={48} /> : <FileBox size={48} />}\n title={\n searchQuery\n ? tr(\n \"export.templates.empty.filtered.title\",\n \"No matching templates\",\n )\n : tr(\"export.templates.empty.title\", \"No templates yet\")\n }\n description={\n searchQuery\n ? tr(\n \"export.templates.empty.filtered.description\",\n \"Try adjusting your search to find what you are looking for.\",\n )\n : tr(\n \"export.templates.empty.description\",\n \"Create a template to save reusable export configurations.\",\n )\n }\n action={\n searchQuery ? (\n <button\n onClick={() => setSearchQuery(\"\")}\n className=\"inline-flex items-center gap-2 px-4 py-2 border-2 border-border rounded-lg hover:bg-accent transition-colors font-medium\"\n >\n <X size={16} />\n {tr(\n \"export.templates.empty.filtered.actions.clear\",\n \"Clear Search\",\n )}\n </button>\n ) : (\n <button\n onClick={handleOpenCreate}\n className=\"inline-flex items-center gap-2 px-4 py-2 bg-primary text-primary-foreground rounded-lg hover:bg-primary/90 transition-colors font-medium\"\n >\n <Plus size={16} />\n {tr(\n \"export.templates.empty.actions.newTemplate\",\n \"New Template\",\n )}\n </button>\n )\n }\n />\n )\n ) : null}\n {templatePendingDelete && (\n <div\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby=\"template-list-delete-title\"\n className=\"fixed inset-0 z-50 flex items-center justify-center bg-background/80 backdrop-blur-sm p-4\"\n >\n <div className=\"w-full max-w-md rounded-xl border-2 border-border bg-card p-6 shadow-xl\">\n <h2 id=\"template-list-delete-title\" className=\"text-lg font-bold\">\n {tr(\"export.templates.delete.title\", \"Delete template?\")}\n </h2>\n <p className=\"mt-2 text-sm text-muted-foreground\">\n {tr(\n \"export.templates.delete.description\",\n \"This removes the saved export configuration. Existing export jobs are not deleted.\",\n )}\n </p>\n <div className=\"mt-6 flex flex-col-reverse sm:flex-row sm:justify-end gap-3\">\n <button\n type=\"button\"\n onClick={() => setTemplatePendingDelete(null)}\n className=\"px-4 py-2 rounded-lg border-2 border-border hover:bg-accent transition-colors font-medium\"\n >\n {tr(\"export.templates.delete.cancel\", \"Keep Template\")}\n </button>\n <button\n type=\"button\"\n onClick={confirmDeleteTemplate}\n className=\"px-4 py-2 rounded-lg bg-destructive text-destructive-foreground hover:bg-destructive/90 transition-colors font-medium\"\n >\n {tr(\"export.templates.delete.confirmAction\", \"Delete Template\")}\n </button>\n </div>\n </div>\n </div>\n )}\n </PageLayout>\n );\n}\n"],"mappings":";;;;;;;;;;;;AA4BA,IAAM,KAAY,GAAc,OACZ,EAAK,SAAS,IAAI,GAAG,EAAK,MAAM,GAAG,GAAG,GAAG,MACzC,EAAK,WAAW,IAAI,GAAG,IAAO,IAAI;AAQtD,SAAgB,IAAsB;CACpC,IAAM,EAAE,cAAW,KAAK,gBAAa,GAAW,EAC1C,EAAE,SAAM,GAAS,EACjB,KACJ,GACA,GACA,MACG,EAAc,GAAG,GAAK,GAAU,EAAO,EACtC,EAAE,MAAM,GAAW,iBAAc,GAAoB,EACrD,EAAE,sBAAmB,GAAyB,EAC9C,EAAE,mBAAgB,WAAW,MAAa,GAAyB,EACnE,EAAE,MAAM,MAAsB,GAAsB,EAEpD,CAAC,GAAa,KAAkB,EAAS,GAAG,EAC5C,CAAC,IAAgB,KAAqB,EAAS,GAAM,EACrD,CAAC,GAAiB,KAAsB,EAAS,GAAG,EACpD,CAAC,GAAwB,KAA6B,EAAS,GAAG,EAClE,CAAC,GAAwB,KAA6B,EAE1D,EAAE,CAAC,EACC,CAAC,GAAmB,KACxB,EAAuB,MAAM,EACzB,CAAC,GAAa,KAAkB,EAAwB,KAAK,EAC7D,CAAC,GAAuB,KAA4B,EAExD,KAAK,EAED,UAAyB;AAM7B,EALA,EAAmB,GAAG,EACtB,EAA0B,GAAG,EAC7B,EAA0B,EAAE,CAAC,EAC7B,EAAqB,MAAM,EAC3B,EAAe,KAAK,EACpB,EAAkB,GAAK;IAGnB,IAAuB,YAAY;AACvC,MAAI,CAAC,EAAgB,MAAM,EAAE;AAC3B,KACE,EACE,6CACA,6BACD,CACF;AACD;;AAEF,MAAI,EAAuB,WAAW,GAAG;AACvC,KACE,EACE,+CACA,mCACD,CACF;AACD;;AAEF,IAAe,KAAK;AACpB,MAAI;AAOF,GANA,MAAM,EAAe;IACnB,MAAM,EAAgB,MAAM;IAC5B,aAAa,EAAuB,MAAM,IAAI,KAAA;IAC9C,aAAa;IACb,QAAQ;IACT,CAAC,EACF,EAAkB,GAAM;WACjB,GAAK;AACZ,KACE,aAAe,QACX,EAAI,UACJ,EACE,6CACA,6BACD,CACN;;IAIC,KAAgB,MAAuB;AAC3C,KAA2B,MACzB,EAAK,SAAS,EAAW,GACrB,EAAK,QAAQ,MAAM,MAAM,EAAW,GACpC,CAAC,GAAG,GAAM,EAAW,CAC1B;IAIG,IAAoB,QAAc;AACtC,MAAI,CAAC,EAAa,QAAO;EACzB,IAAM,IAAI,EAAY,aAAa;AACnC,SAAO,EAAU,QACd,MACC,EAAE,KAAK,aAAa,CAAC,SAAS,EAAE,IAChC,EAAE,YAAY,MAAM,MAAM,EAAE,aAAa,CAAC,SAAS,EAAE,CAAC,CACzD;IACA,CAAC,GAAW,EAAY,CAAC,EAEtB,KAAuB,MAAuB;AAClD,MAAW,EAAS,GAAU,aAAa,IAAa,CAAC;IAGrD,KAAuB,OAC3B,GACA,MACG;AAGH,EAFA,EAAE,iBAAiB,EACnB,EAAa,SAAS,EACtB,EAAyB,EAAW;IAGhC,KAAwB,YAAY;AACnC,SACL;OAAI;AAEF,IADA,MAAM,EAAe,EAAsB,EAC3C,EAAa,UAAU;WACjB;AACN,MAAa,QAAQ;;AAEvB,KAAyB,KAAK;;;AAGhC,QACE,kBAAC,GAAD;EACE,OAAO,EAAG,0BAA0B,mBAAmB;EACvD,UAAU,EACR,6BACA,yDACD;EACD,MAAM,kBAAC,GAAD,EAAS,MAAM,IAAM,CAAA;EAC3B,eACE,kBAAC,OAAD;GAAK,WAAU;aAAf,CACE,kBAAC,UAAD;IACE,SAAS;IACT,WAAU;cAFZ,CAIE,kBAAC,GAAD,EAAM,MAAM,IAAM,CAAA,EACjB,EAAG,wCAAwC,eAAe,CACpD;OACT,kBAAC,UAAD;IACE,eAAe,IAAW,EAAS,GAAU,MAAM,CAAC;IACpD,WAAU;cAFZ,CAIE,kBAAC,GAAD,EAAM,MAAM,IAAM,CAAA,EACjB,EAAG,sCAAsC,aAAa,CAChD;MACL;;EAER,eACE,kBAAC,QAAD;GAAM,WAAU;aAAhB,CACE,kBAAC,GAAD,EAAU,MAAM,IAAM,CAAA,EACrB,EACC,sCACA,sCACA;IACE,OAAO,EAAkB;IACzB,QAAQ,EAAkB,WAAW,IAAU,KAAN;IAC1C,CACF,CACI;;YApCX;GAwCG,MACC,kBAAC,OAAD;IAAK,WAAU;cAAf;KACE,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,MAAD;OAAI,WAAU;iBACX,EAAG,+BAA+B,eAAe;OAC/C,CAAA,EACL,kBAAC,UAAD;OACE,eAAe,EAAkB,GAAM;OACvC,WAAU;iBAEV,kBAAC,GAAD,EAAG,MAAM,IAAM,CAAA;OACR,CAAA,CACL;;KACL,KACC,kBAAC,KAAD;MAAG,WAAU;gBACV;MACC,CAAA;KAEN,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,SAAD;QAAO,WAAU;kBAAjB,CACG,EAAG,qCAAqC,OAAO,EAAC,KAC3C;WACR,kBAAC,SAAD;QACE,MAAK;QACL,aAAa,EACX,gDACA,0BACD;QACD,OAAO;QACP,WAAW,MAAM,EAAmB,EAAE,OAAO,MAAM;QACnD,WAAU;QACV,CAAA,CACE;UACN,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,SAAD;QAAO,WAAU;kBAAjB,CACG,EAAG,uCAAuC,SAAS,EAAC,KAC/C;WACR,kBAAC,UAAD;QACE,OAAO;QACP,WAAW,MACT,EAAqB,EAAE,OAAO,MAAsB;QAEtD,WAAU;kBALZ,CAOE,kBAAC,UAAD;SAAQ,OAAM;mBAAM;SAAY,CAAA,EAChC,kBAAC,UAAD;SAAQ,OAAM;mBAAO;SAAa,CAAA,CAC3B;UACL;SACF;;KACN,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,SAAD;OAAO,WAAU;iBACd,EAAG,4CAA4C,cAAc;OACxD,CAAA,EACR,kBAAC,SAAD;OACE,MAAK;OACL,aAAa,EACX,uDACA,uBACD;OACD,OAAO;OACP,WAAW,MAAM,EAA0B,EAAE,OAAO,MAAM;OAC1D,WAAU;OACV,CAAA,CACE;;KACN,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,SAAD;OAAO,WAAU;iBAAjB;QACG,EAAG,4CAA4C,eAAe;QAAC;QAAG;QACnE,kBAAC,QAAD;SAAM,WAAU;mBACb,EACC,gDACA,wBACD;SACI,CAAA;QACD;UACR,kBAAC,OAAD;OAAK,WAAU;iBACZ,EAAkB,KAAK,MACtB,kBAAC,UAAD;QAEE,MAAK;QACL,eAAe,EAAa,EAAO,WAAW;QAC9C,WAAW,EACT,sEACA,EAAuB,SAAS,EAAO,WAAW,GAC9C,8CACA,sDACL;kBAEA,EAAO;QACD,EAXF,EAAO,WAWL,CACT;OACE,CAAA,CACF;;KACN,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,UAAD;OACE,SAAS;OACT,UAAU;OACV,WAAU;iBAHZ,CAKG,IACC,kBAAC,GAAD;QAAS,MAAM;QAAI,WAAU;QAAiB,CAAA,GAE9C,kBAAC,GAAD,EAAM,MAAM,IAAM,CAAA,EAEnB,EAAG,wCAAwC,kBAAkB,CACvD;UACT,kBAAC,UAAD;OACE,eAAe,EAAkB,GAAM;OACvC,WAAU;iBAET,EAAG,wCAAwC,SAAS;OAC9C,CAAA,CACL;;KACF;;GAGR,kBAAC,OAAD;IAAK,WAAU;cAAf;KACE,kBAAC,GAAD;MACE,MAAM;MACN,WAAU;MACV,CAAA;KACF,kBAAC,SAAD;MACE,MAAK;MACL,aAAa,EACX,uCACA,sBACD;MACD,OAAO;MACP,WAAW,MAAM,EAAe,EAAE,OAAO,MAAM;MAC/C,WAAU;MACV,CAAA;KACD,KACC,kBAAC,UAAD;MACE,eAAe,EAAe,GAAG;MACjC,WAAU;gBAEV,kBAAC,GAAD,EAAG,MAAM,IAAM,CAAA;MACR,CAAA;KAEP;;GAGL,KACC,kBAAC,OAAD;IAAK,WAAU;cACZ,CAAC,GAAG;;;;;KAAQ,CAAC,CAAC,KAAK,GAAG,MACrB,kBAAC,OAAD;KAEE,WAAU;eAFZ;MAIE,kBAAC,OAAD,EAAK,WAAU,kCAAmC,CAAA;MAClD,kBAAC,OAAD,EAAK,WAAU,oCAAqC,CAAA;MACpD,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,OAAD,EAAK,WAAU,kCAAmC,CAAA,EAClD,kBAAC,OAAD,EAAK,WAAU,kCAAmC,CAAA,CAC9C;;MACF;OATC,EASD,CACN;IACE,CAAA;GAIN,IA8IE,OA7IF,EAAkB,SAAS,IACzB,kBAAC,OAAD;IAAK,WAAU;cACZ,EAAkB,KAAK,GAAU,MAChC,kBAAC,OAAD;KAEE,MAAK;KACL,UAAU;KACV,eAAe,EAAoB,EAAS,GAAG;KAC/C,YAAY,MAAM;AAChB,OAAI,EAAE,QAAQ,WAAW,EAAE,QAAQ,SACjC,EAAE,gBAAgB,EAClB,EAAoB,EAAS,GAAG;;KAGpC,WAAW,EACT,uFACA,uEACA,8CACD;KACD,OAAO,EAAE,gBAAgB,GAAG,IAAQ,GAAG,KAAK;eAhB9C,CAmBE,kBAAC,OAAD;MAAK,WAAU;gBACb,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,OAAD;SAAK,WAAU;mBACb,kBAAC,GAAD;UAAS,MAAM;UAAI,WAAU;UAAiB,CAAA;SAC1C,CAAA,EACN,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,MAAD;SAAI,WAAU;mBAAiB,EAAS;SAAU,CAAA,EAClD,kBAAC,KAAD;SAAG,WAAU;mBAAb,CACG,EAAqB,EAAS,OAAO,EACrC,EAAS,aACR,kBAAC,QAAD;UAAM,WAAU;oBACb,EAAG,iCAAiC,UAAU;UAC1C,CAAA,CAEP;WACA,EAAA,CAAA,CACF;WACN,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,UAAD;SACE,UAAU,MAAM,GAAqB,GAAG,EAAS,GAAG;SACpD,WAAU;SACV,cAAY,EACV,yCACA,iBACA,EAAE,MAAM,EAAS,MAAM,CACxB;mBAED,kBAAC,GAAD,EAAG,MAAM,IAAM,CAAA;SACR,CAAA,EACT,kBAAC,IAAD;SACE,MAAM;SACN,WAAU;SACV,CAAA,CACE;UACF;;MACF,CAAA,EAGN,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACG,EAAS,eACR,kBAAC,KAAD;OAAG,WAAU;iBACV,EAAS;OACR,CAAA,EAEN,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACG,EAAS,YAAY,MAAM,GAAG,EAAE,CAAC,KAAK,MACrC,kBAAC,QAAD;QAEE,WAAU;kBAET;QACI,EAJA,EAIA,CACP,EACD,EAAS,YAAY,SAAS,KAC7B,kBAAC,QAAD;QAAM,WAAU;kBACb,EACC,sCACA,iBACA,EACE,OAAO,EAAS,YAAY,SAAS,GACtC,CACF;QACI,CAAA,CAEL;SACF;QACF;OArFC,EAAS,GAqFV,CACN;IACE,CAAA,GAEN,kBAAC,GAAD;IACE,MAAoB,EAAd,IAAe,IAAuB,GAAxB,EAAQ,MAAM,IAAM,CAAwB;IAChE,OACE,IACI,EACE,yCACA,wBACD,GACD,EAAG,gCAAgC,mBAAmB;IAE5D,aACE,IACI,EACE,+CACA,8DACD,GACD,EACE,sCACA,4DACD;IAEP,QACE,IACE,kBAAC,UAAD;KACE,eAAe,EAAe,GAAG;KACjC,WAAU;eAFZ,CAIE,kBAAC,GAAD,EAAG,MAAM,IAAM,CAAA,EACd,EACC,iDACA,eACD,CACM;SAET,kBAAC,UAAD;KACE,SAAS;KACT,WAAU;eAFZ,CAIE,kBAAC,GAAD,EAAM,MAAM,IAAM,CAAA,EACjB,EACC,8CACA,eACD,CACM;;IAGb,CAAA;GAGL,KACC,kBAAC,OAAD;IACE,MAAK;IACL,cAAW;IACX,mBAAgB;IAChB,WAAU;cAEV,kBAAC,OAAD;KAAK,WAAU;eAAf;MACE,kBAAC,MAAD;OAAI,IAAG;OAA6B,WAAU;iBAC3C,EAAG,iCAAiC,mBAAmB;OACrD,CAAA;MACL,kBAAC,KAAD;OAAG,WAAU;iBACV,EACC,uCACA,qFACD;OACC,CAAA;MACJ,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,UAAD;QACE,MAAK;QACL,eAAe,EAAyB,KAAK;QAC7C,WAAU;kBAET,EAAG,kCAAkC,gBAAgB;QAC/C,CAAA,EACT,kBAAC,UAAD;QACE,MAAK;QACL,SAAS;QACT,WAAU;kBAET,EAAG,yCAAyC,kBAAkB;QACxD,CAAA,CACL;;MACF;;IACF,CAAA;GAEG"}
1
+ {"version":3,"file":"ExportTemplatesPage.js","names":[],"sources":["../../../src/export/pages/ExportTemplatesPage.tsx"],"sourcesContent":["import { useState, useMemo } from \"react\";\nimport {\n Search,\n X,\n FileBox,\n Plus,\n ChevronRight,\n Sparkles,\n Loader2,\n} from \"lucide-react\";\nimport { useI18n } from \"@burdenoff/fe-libs/shared/providers/shell/I18nProvider\";\nimport { useExport } from \"../providers/ExportProvider\";\nimport {\n useExportTemplates,\n useDeleteExportTemplate,\n useCreateExportTemplate,\n useAvailableEntities,\n} from \"../hooks/useExportQueries\";\nimport { PageLayout, EmptyState } from \"../components/PageLayout\";\nimport { getFormatDisplayName } from \"../constants/enums\";\nimport { cn } from \"../utils/cn\";\nimport { tWithFallback } from \"../utils/i18n\";\nimport type { ExportFormat } from \"../types\";\nimport { nativeImpact, nativeNotify } from \"../../utils/nativeBridge\";\n\n/**\n * Helper to join paths correctly\n */\nconst joinPath = (base: string, path: string): string => {\n const cleanBase = base.endsWith(\"/\") ? base.slice(0, -1) : base;\n const cleanPath = path.startsWith(\"/\") ? path : `/${path}`;\n return cleanBase + cleanPath;\n};\n\n/**\n * Export Templates Page\n * Template management list for reusable export configurations\n */\nexport function ExportTemplatesPage() {\n const { basePath = \"/\", navigate } = useExport();\n const { t } = useI18n();\n const tr = (\n key: string,\n fallback: string,\n params?: Record<string, string | number>,\n ) => tWithFallback(t, key, fallback, params);\n const { data: templates, isLoading } = useExportTemplates();\n const { deleteTemplate } = useDeleteExportTemplate();\n const { createTemplate, isPending: creating } = useCreateExportTemplate();\n const { data: availableEntities } = useAvailableEntities();\n\n const [searchQuery, setSearchQuery] = useState(\"\");\n const [showCreateForm, setShowCreateForm] = useState(false);\n const [newTemplateName, setNewTemplateName] = useState(\"\");\n const [newTemplateDescription, setNewTemplateDescription] = useState(\"\");\n const [newTemplateEntityTypes, setNewTemplateEntityTypes] = useState<\n string[]\n >([]);\n const [newTemplateFormat, setNewTemplateFormat] =\n useState<ExportFormat>(\"CSV\");\n const [createError, setCreateError] = useState<string | null>(null);\n const [templatePendingDelete, setTemplatePendingDelete] = useState<\n string | null\n >(null);\n\n const handleOpenCreate = () => {\n setNewTemplateName(\"\");\n setNewTemplateDescription(\"\");\n setNewTemplateEntityTypes([]);\n setNewTemplateFormat(\"CSV\");\n setCreateError(null);\n setShowCreateForm(true);\n };\n\n const handleCreateTemplate = async () => {\n if (!newTemplateName.trim()) {\n setCreateError(\n tr(\n \"export.templates.form.errors.nameRequired\",\n \"Template name is required.\",\n ),\n );\n return;\n }\n if (newTemplateEntityTypes.length === 0) {\n setCreateError(\n tr(\n \"export.templates.form.errors.entityRequired\",\n \"Select at least one entity type.\",\n ),\n );\n return;\n }\n setCreateError(null);\n try {\n await createTemplate({\n name: newTemplateName.trim(),\n description: newTemplateDescription.trim() || undefined,\n entityTypes: newTemplateEntityTypes,\n format: newTemplateFormat,\n });\n setShowCreateForm(false);\n } catch (err) {\n setCreateError(\n err instanceof Error\n ? err.message\n : tr(\n \"export.templates.form.errors.createFailed\",\n \"Failed to create template.\",\n ),\n );\n }\n };\n\n const toggleEntity = (entityType: string) => {\n setNewTemplateEntityTypes((prev) =>\n prev.includes(entityType)\n ? prev.filter((e) => e !== entityType)\n : [...prev, entityType],\n );\n };\n\n // Client-side search filter\n const filteredTemplates = useMemo(() => {\n if (!searchQuery) return templates;\n const q = searchQuery.toLowerCase();\n return templates.filter(\n (t) =>\n t.name.toLowerCase().includes(q) ||\n t.entityTypes.some((e) => e.toLowerCase().includes(q)),\n );\n }, [templates, searchQuery]);\n\n const handleTemplateClick = (templateId: string) => {\n navigate?.(joinPath(basePath, `templates/${templateId}`));\n };\n\n const handleDeleteTemplate = async (\n e: React.MouseEvent,\n templateId: string,\n ) => {\n e.stopPropagation();\n nativeImpact(\"medium\");\n setTemplatePendingDelete(templateId);\n };\n\n const confirmDeleteTemplate = async () => {\n if (!templatePendingDelete) return;\n try {\n await deleteTemplate(templatePendingDelete);\n nativeNotify(\"success\");\n } catch {\n nativeNotify(\"error\");\n }\n setTemplatePendingDelete(null);\n };\n\n return (\n <PageLayout\n title={tr(\"export.templates.title\", \"Export Templates\")}\n subtitle={tr(\n \"export.templates.subtitle\",\n \"Reusable export configurations for common data exports\",\n )}\n icon={<FileBox size={24} />}\n headerActions={\n <div className=\"flex flex-wrap items-center gap-2\">\n <button\n type=\"button\"\n onClick={handleOpenCreate}\n className=\"inline-flex items-center gap-2 px-3 py-2 sm:px-4 bg-primary text-primary-foreground rounded-lg hover:bg-primary/90 transition-colors font-medium text-sm\"\n >\n <Plus size={16} />\n {tr(\"export.templates.actions.newTemplate\", \"New Template\")}\n </button>\n <button\n type=\"button\"\n onClick={() => navigate?.(joinPath(basePath, \"new\"))}\n className=\"inline-flex items-center gap-2 px-3 py-2 sm:px-4 border-2 border-border rounded-lg hover:bg-accent transition-colors font-medium text-sm\"\n >\n <Plus size={16} />\n {tr(\"export.templates.actions.newExport\", \"New Export\")}\n </button>\n </div>\n }\n headerContent={\n <span className=\"inline-flex items-center gap-1.5 px-2.5 py-0.5 rounded-full text-xs font-medium bg-muted text-muted-foreground\">\n <Sparkles size={12} />\n {tr(\n \"export.templates.summary.available\",\n \"{count} template{suffix} available\",\n {\n count: filteredTemplates.length,\n suffix: filteredTemplates.length !== 1 ? \"s\" : \"\",\n },\n )}\n </span>\n }\n >\n {/* Create Template Form */}\n {showCreateForm && (\n <div className=\"border-2 border-primary/30 rounded-xl p-6 bg-primary/5 space-y-4\">\n <div className=\"flex items-center justify-between\">\n <h3 className=\"font-semibold text-lg\">\n {tr(\"export.templates.form.title\", \"New Template\")}\n </h3>\n <button\n type=\"button\"\n onClick={() => setShowCreateForm(false)}\n className=\"p-1.5 rounded-md hover:bg-accent\"\n >\n <X size={16} />\n </button>\n </div>\n {createError && (\n <p className=\"text-sm text-destructive bg-destructive/10 rounded-lg px-3 py-2\">\n {createError}\n </p>\n )}\n <div className=\"grid grid-cols-1 sm:grid-cols-2 gap-4\">\n <div className=\"space-y-1\">\n <label className=\"text-sm font-medium\">\n {tr(\"export.templates.form.fields.name\", \"Name\")} *\n </label>\n <input\n type=\"text\"\n aria-label={tr(\"export.templates.form.fields.name\", \"Name\")}\n placeholder={tr(\n \"export.templates.form.fields.namePlaceholder\",\n \"e.g. Weekly Tags Export\",\n )}\n value={newTemplateName}\n onChange={(e) => setNewTemplateName(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 transition-all\"\n />\n </div>\n <div className=\"space-y-1\">\n <label className=\"text-sm font-medium\">\n {tr(\"export.templates.form.fields.format\", \"Format\")} *\n </label>\n <select\n value={newTemplateFormat}\n onChange={(e) =>\n setNewTemplateFormat(e.target.value as ExportFormat)\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 transition-all\"\n >\n <option value=\"CSV\">CSV</option>\n <option value=\"JSON\">JSON</option>\n </select>\n </div>\n </div>\n <div className=\"space-y-1\">\n <label className=\"text-sm font-medium\">\n {tr(\"export.templates.form.fields.description\", \"Description\")}\n </label>\n <input\n type=\"text\"\n aria-label={tr(\n \"export.templates.form.fields.description\",\n \"Description\",\n )}\n placeholder={tr(\n \"export.templates.form.fields.descriptionPlaceholder\",\n \"Optional description\",\n )}\n value={newTemplateDescription}\n onChange={(e) => setNewTemplateDescription(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 transition-all\"\n />\n </div>\n <div className=\"space-y-2\">\n <label className=\"text-sm font-medium\">\n {tr(\"export.templates.form.fields.entityTypes\", \"Entity Types\")} *{\" \"}\n <span className=\"text-muted-foreground font-normal\">\n {tr(\n \"export.templates.form.fields.entityTypesHint\",\n \"(select at least one)\",\n )}\n </span>\n </label>\n <div className=\"flex flex-wrap gap-2\">\n {availableEntities.map((entity) => (\n <button\n key={entity.entityType}\n type=\"button\"\n onClick={() => toggleEntity(entity.entityType)}\n className={cn(\n \"px-3 py-1.5 rounded-lg text-sm font-medium border-2 transition-all\",\n newTemplateEntityTypes.includes(entity.entityType)\n ? \"border-primary bg-primary/10 text-primary\"\n : \"border-border bg-background hover:border-primary/50\",\n )}\n >\n {entity.displayName}\n </button>\n ))}\n </div>\n </div>\n <div className=\"flex gap-3 pt-2\">\n <button\n type=\"button\"\n onClick={handleCreateTemplate}\n disabled={creating}\n className=\"inline-flex items-center gap-2 px-5 py-2.5 bg-primary text-primary-foreground rounded-lg hover:bg-primary/90 transition-colors font-medium disabled:opacity-50\"\n >\n {creating ? (\n <Loader2 size={16} className=\"animate-spin\" />\n ) : (\n <Plus size={16} />\n )}\n {tr(\"export.templates.form.actions.create\", \"Create Template\")}\n </button>\n <button\n type=\"button\"\n onClick={() => setShowCreateForm(false)}\n className=\"px-5 py-2.5 border-2 border-border rounded-lg hover:bg-accent transition-colors font-medium\"\n >\n {tr(\"export.templates.form.actions.cancel\", \"Cancel\")}\n </button>\n </div>\n </div>\n )}\n {/* Search */}\n <div className=\"relative group\">\n <Search\n size={18}\n className=\"absolute left-3 top-1/2 -translate-y-1/2 text-muted-foreground group-focus-within:text-primary transition-colors\"\n />\n <input\n type=\"text\"\n aria-label={tr(\n \"export.templates.search.placeholder\",\n \"Search templates\",\n )}\n placeholder={tr(\n \"export.templates.search.placeholder\",\n \"Search templates...\",\n )}\n value={searchQuery}\n onChange={(e) => setSearchQuery(e.target.value)}\n className=\"w-full pl-[3.25rem] pr-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 />\n {searchQuery && (\n <button\n type=\"button\"\n onClick={() => setSearchQuery(\"\")}\n className=\"absolute right-3 top-1/2 -translate-y-1/2 p-1 rounded-md text-muted-foreground hover:text-foreground hover:bg-accent\"\n >\n <X size={16} />\n </button>\n )}\n </div>\n\n {/* Loading */}\n {isLoading && (\n <div className=\"grid grid-cols-1 lg:grid-cols-2 gap-4\">\n {[...Array(4)].map((_, i) => (\n <div\n key={i}\n className=\"border-2 border-border/50 rounded-xl p-5 animate-pulse\"\n >\n <div className=\"h-5 w-40 bg-muted rounded mb-3\" />\n <div className=\"h-3 w-full bg-muted rounded mb-2\" />\n <div className=\"flex gap-2 mt-4\">\n <div className=\"h-5 w-16 bg-muted rounded-full\" />\n <div className=\"h-5 w-16 bg-muted rounded-full\" />\n </div>\n </div>\n ))}\n </div>\n )}\n\n {/* Templates Grid */}\n {!isLoading ? (\n filteredTemplates.length > 0 ? (\n <div className=\"grid grid-cols-1 lg:grid-cols-2 gap-4\">\n {filteredTemplates.map((template, index) => (\n <div\n key={template.id}\n role=\"button\"\n tabIndex={0}\n onClick={() => handleTemplateClick(template.id)}\n onKeyDown={(e) => {\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n handleTemplateClick(template.id);\n }\n }}\n className={cn(\n \"text-left group cursor-pointer border-2 border-border/50 rounded-xl overflow-hidden\",\n \"hover:shadow-md hover:border-primary/30 transition-all duration-200\",\n \"animate-in fade-in-0 slide-in-from-bottom-2\",\n )}\n style={{ animationDelay: `${index * 50}ms` }}\n >\n {/* Header */}\n <div className=\"p-4 border-b bg-muted/30\">\n <div className=\"flex items-start justify-between\">\n <div className=\"flex items-center gap-3\">\n <div className=\"p-2 rounded-lg bg-primary/10\">\n <FileBox size={20} className=\"text-primary\" />\n </div>\n <div>\n <h3 className=\"font-semibold\">{template.name}</h3>\n <p className=\"text-xs text-muted-foreground\">\n {getFormatDisplayName(template.format)}\n {template.isDefault && (\n <span className=\"ml-1.5 inline-flex items-center px-1.5 py-0.5 rounded text-xs bg-primary/10 text-primary font-medium\">\n {tr(\"export.templates.card.default\", \"Default\")}\n </span>\n )}\n </p>\n </div>\n </div>\n <div className=\"flex items-center gap-2\">\n <button\n type=\"button\"\n onClick={(e) => handleDeleteTemplate(e, template.id)}\n className=\"p-1.5 rounded-md text-muted-foreground hover:text-destructive hover:bg-destructive/10 transition-colors\"\n aria-label={tr(\n \"export.templates.card.deleteAriaLabel\",\n \"Delete {name}\",\n { name: template.name },\n )}\n >\n <X size={14} />\n </button>\n <ChevronRight\n size={18}\n className=\"text-muted-foreground group-hover:text-primary transition-colors mt-1\"\n />\n </div>\n </div>\n </div>\n\n {/* Body */}\n <div className=\"p-4\">\n {template.description && (\n <p className=\"text-sm text-muted-foreground mb-3 line-clamp-2\">\n {template.description}\n </p>\n )}\n <div className=\"flex flex-wrap gap-1.5 overflow-hidden\">\n {template.entityTypes.slice(0, 6).map((entity) => (\n <span\n key={entity}\n className=\"inline-flex px-2 py-0.5 rounded text-xs font-medium bg-muted text-muted-foreground max-w-full truncate\"\n >\n {entity}\n </span>\n ))}\n {template.entityTypes.length > 6 && (\n <span className=\"inline-flex px-2 py-0.5 rounded text-xs font-medium bg-muted text-muted-foreground\">\n {tr(\n \"export.templates.card.moreEntities\",\n \"+{count} more\",\n {\n count: template.entityTypes.length - 6,\n },\n )}\n </span>\n )}\n </div>\n </div>\n </div>\n ))}\n </div>\n ) : (\n <EmptyState\n icon={searchQuery ? <Search size={48} /> : <FileBox size={48} />}\n title={\n searchQuery\n ? tr(\n \"export.templates.empty.filtered.title\",\n \"No matching templates\",\n )\n : tr(\"export.templates.empty.title\", \"No templates yet\")\n }\n description={\n searchQuery\n ? tr(\n \"export.templates.empty.filtered.description\",\n \"Try adjusting your search to find what you are looking for.\",\n )\n : tr(\n \"export.templates.empty.description\",\n \"Create a template to save reusable export configurations.\",\n )\n }\n action={\n searchQuery ? (\n <button\n type=\"button\"\n onClick={() => setSearchQuery(\"\")}\n className=\"inline-flex items-center gap-2 px-4 py-2 border-2 border-border rounded-lg hover:bg-accent transition-colors font-medium\"\n >\n <X size={16} />\n {tr(\n \"export.templates.empty.filtered.actions.clear\",\n \"Clear Search\",\n )}\n </button>\n ) : (\n <button\n type=\"button\"\n onClick={handleOpenCreate}\n className=\"inline-flex items-center gap-2 px-4 py-2 bg-primary text-primary-foreground rounded-lg hover:bg-primary/90 transition-colors font-medium\"\n >\n <Plus size={16} />\n {tr(\n \"export.templates.empty.actions.newTemplate\",\n \"New Template\",\n )}\n </button>\n )\n }\n />\n )\n ) : null}\n {templatePendingDelete && (\n <div\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby=\"template-list-delete-title\"\n className=\"fixed inset-0 z-50 flex items-center justify-center bg-background/80 backdrop-blur-sm p-4\"\n >\n <div className=\"w-full max-w-md rounded-xl border-2 border-border bg-card p-6 shadow-xl\">\n <h2 id=\"template-list-delete-title\" className=\"text-lg font-bold\">\n {tr(\"export.templates.delete.title\", \"Delete template?\")}\n </h2>\n <p className=\"mt-2 text-sm text-muted-foreground\">\n {tr(\n \"export.templates.delete.description\",\n \"This removes the saved export configuration. Existing export jobs are not deleted.\",\n )}\n </p>\n <div className=\"mt-6 flex flex-col-reverse sm:flex-row sm:justify-end gap-3\">\n <button\n type=\"button\"\n onClick={() => setTemplatePendingDelete(null)}\n className=\"px-4 py-2 rounded-lg border-2 border-border hover:bg-accent transition-colors font-medium\"\n >\n {tr(\"export.templates.delete.cancel\", \"Keep Template\")}\n </button>\n <button\n type=\"button\"\n onClick={confirmDeleteTemplate}\n className=\"px-4 py-2 rounded-lg bg-destructive text-destructive-foreground hover:bg-destructive/90 transition-colors font-medium\"\n >\n {tr(\"export.templates.delete.confirmAction\", \"Delete Template\")}\n </button>\n </div>\n </div>\n </div>\n )}\n </PageLayout>\n );\n}\n"],"mappings":"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"}
@@ -18,7 +18,7 @@ function w() {
18
18
  className: "animate-spin text-primary"
19
19
  }), /* @__PURE__ */ x("span", {
20
20
  className: "mt-6 text-sm font-medium text-muted-foreground",
21
- children: "Loading template details..."
21
+ children: "Loading template details"
22
22
  })]
23
23
  }) : k ? /* @__PURE__ */ S(a, {
24
24
  showHeader: !1,
@@ -28,6 +28,7 @@ function w() {
28
28
  children: /* @__PURE__ */ S("div", {
29
29
  className: "relative z-10 flex items-center gap-4",
30
30
  children: [/* @__PURE__ */ x("button", {
31
+ type: "button",
31
32
  onClick: () => E?.(C(T, "templates")),
32
33
  className: "p-2.5 hover:bg-accent rounded-lg transition-all duration-200",
33
34
  children: /* @__PURE__ */ x(d, { size: 20 })
@@ -110,12 +111,14 @@ function w() {
110
111
  /* @__PURE__ */ S("div", {
111
112
  className: "flex flex-col sm:flex-row gap-3 pt-2",
112
113
  children: [/* @__PURE__ */ S("button", {
114
+ type: "button",
113
115
  onClick: () => {
114
116
  E?.(C(T, `new?templateId=${w}`));
115
117
  },
116
118
  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",
117
119
  children: [/* @__PURE__ */ x(v, { size: 18 }), "Use Template"]
118
120
  }), !k.isDefault && /* @__PURE__ */ S("button", {
121
+ type: "button",
119
122
  onClick: () => O(!0),
120
123
  disabled: M,
121
124
  className: "inline-flex items-center justify-center gap-2 px-6 py-3 border-2 border-status-error-bg/50 text-status-error-text rounded-lg hover:bg-status-error-bg-subtle transition-all duration-200 font-medium disabled:opacity-50",
@@ -178,6 +181,7 @@ function w() {
178
181
  children: [/* @__PURE__ */ S("div", {
179
182
  className: "flex items-center gap-3 mb-6",
180
183
  children: [/* @__PURE__ */ x("button", {
184
+ type: "button",
181
185
  onClick: () => E?.(C(T, "templates")),
182
186
  className: "p-2.5 hover:bg-accent rounded-lg transition-all duration-200",
183
187
  children: /* @__PURE__ */ x(d, { size: 20 })
@@ -201,6 +205,7 @@ function w() {
201
205
  children: "The template you are looking for does not exist."
202
206
  }),
203
207
  /* @__PURE__ */ S("button", {
208
+ type: "button",
204
209
  onClick: () => E?.(C(T, "templates")),
205
210
  className: "inline-flex items-center gap-2 px-6 py-3 bg-primary text-primary-foreground rounded-lg hover:bg-primary/90 transition-colors font-medium",
206
211
  children: [/* @__PURE__ */ x(d, { size: 18 }), "Back to Templates"]
@@ -1 +1 @@
1
- {"version":3,"file":"TemplateDetailPage.js","names":[],"sources":["../../../src/export/pages/TemplateDetailPage.tsx"],"sourcesContent":["import { useParams } from \"react-router-dom\";\nimport { useState } from \"react\";\nimport {\n ArrowLeft,\n FileBox,\n Download,\n Play,\n Trash2,\n AlertCircle,\n Clock,\n FileText,\n HardDrive,\n Loader2,\n} from \"lucide-react\";\nimport { useExport } from \"../providers/ExportProvider\";\nimport {\n useExportTemplate,\n useDeleteExportTemplate,\n} from \"../hooks/useExportQueries\";\nimport {\n getFormatDisplayName,\n getArchiveFormatDisplayName,\n} from \"../constants/enums\";\nimport { PageLayout, PageSection } from \"../components/PageLayout\";\nimport { nativeImpact, nativeNotify } from \"../../utils/nativeBridge\";\n\n/**\n * Helper to join paths correctly\n */\nconst joinPath = (base: string, path: string): string => {\n const cleanBase = base.endsWith(\"/\") ? base.slice(0, -1) : base;\n const cleanPath = path.startsWith(\"/\") ? path : `/${path}`;\n return cleanBase + cleanPath;\n};\n\n/**\n * Template Detail Page\n * View template details and use it to create a new export.\n * Fetches template from the backend via useExportTemplate hook.\n */\nexport function TemplateDetailPage() {\n const { templateId } = useParams<{ templateId: string }>();\n const { basePath = \"/\", navigate } = useExport();\n const [showDeleteConfirm, setShowDeleteConfirm] = useState(false);\n\n const { data: template, isLoading } = useExportTemplate(templateId);\n const { deleteTemplate, isPending: deleting } = useDeleteExportTemplate();\n\n // Loading\n if (isLoading) {\n return (\n <div className=\"flex flex-col items-center justify-center py-20\">\n <Loader2 size={48} className=\"animate-spin text-primary\" />\n <span className=\"mt-6 text-sm font-medium text-muted-foreground\">\n Loading template details...\n </span>\n </div>\n );\n }\n\n if (!template) {\n return (\n <PageLayout showHeader={false}>\n <div className=\"flex items-center gap-3 mb-6\">\n <button\n onClick={() => navigate?.(joinPath(basePath, \"templates\"))}\n className=\"p-2.5 hover:bg-accent rounded-lg transition-all duration-200\"\n >\n <ArrowLeft size={20} />\n </button>\n <h1 className=\"text-xl font-bold\">Template Not Found</h1>\n </div>\n <div className=\"border-2 border-border-default rounded-xl bg-status-error-bg-subtle p-12 text-center\">\n <AlertCircle\n size={48}\n className=\"text-status-error-text mx-auto mb-4\"\n />\n <h3 className=\"text-lg font-bold text-status-error-text mb-2\">\n Template Not Found\n </h3>\n <p className=\"text-status-error-text mb-6\">\n The template you are looking for does not exist.\n </p>\n <button\n onClick={() => navigate?.(joinPath(basePath, \"templates\"))}\n className=\"inline-flex items-center gap-2 px-6 py-3 bg-primary text-primary-foreground rounded-lg hover:bg-primary/90 transition-colors font-medium\"\n >\n <ArrowLeft size={18} />\n Back to Templates\n </button>\n </div>\n </PageLayout>\n );\n }\n\n const handleUseTemplate = () => {\n // Navigate to new export page pre-selected with this template\n navigate?.(joinPath(basePath, `new?templateId=${templateId}`));\n };\n\n const handleDelete = async () => {\n if (!templateId) return;\n nativeImpact(\"medium\");\n try {\n await deleteTemplate(templateId);\n nativeNotify(\"success\");\n navigate?.(joinPath(basePath, \"templates\"));\n } catch {\n nativeNotify(\"error\");\n }\n };\n\n return (\n <PageLayout showHeader={false}>\n {/* Header */}\n <div className=\"relative overflow-hidden rounded-xl bg-gradient-to-br from-primary/5 via-primary/3 to-background border border-border/50 p-6 shadow-sm\">\n <div className=\"relative z-10 flex items-center gap-4\">\n <button\n onClick={() => navigate?.(joinPath(basePath, \"templates\"))}\n className=\"p-2.5 hover:bg-accent rounded-lg transition-all duration-200\"\n >\n <ArrowLeft size={20} />\n </button>\n <div className=\"flex items-center gap-3 flex-1\">\n <div className=\"p-2.5 rounded-lg bg-primary/10\">\n <FileBox size={24} className=\"text-primary\" />\n </div>\n <div className=\"flex-1 min-w-0\">\n <h1 className=\"text-xl sm:text-2xl font-bold truncate\">\n {template.name}\n </h1>\n <p className=\"text-sm text-muted-foreground mt-1\">\n {template.isDefault ? \"Default template\" : \"Custom template\"}\n </p>\n </div>\n </div>\n </div>\n </div>\n\n {/* Description */}\n {template.description && (\n <div className=\"border-2 border-border/50 rounded-xl p-5\">\n <p className=\"text-sm text-muted-foreground\">\n {template.description}\n </p>\n </div>\n )}\n\n {/* Info Grid */}\n <div className=\"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4\">\n {[\n {\n icon: <FileText size={18} />,\n label: \"Format\",\n value: getFormatDisplayName(template.format),\n },\n {\n icon: <HardDrive size={18} />,\n label: \"Archive\",\n // Backend template doesn't carry archiveFormat, default to ZIP\n value: getArchiveFormatDisplayName(\"ZIP\"),\n },\n {\n icon: <Download size={18} />,\n label: \"Entity Types\",\n value: `${template.entityTypes.length} type${template.entityTypes.length !== 1 ? \"s\" : \"\"}`,\n },\n {\n icon: <Clock size={18} />,\n label: \"Last Updated\",\n value: new Date(template.updatedAt).toLocaleDateString(),\n },\n ].map((item) => (\n <div\n key={item.label}\n className=\"border-2 border-border/50 rounded-xl p-4 bg-gradient-to-br from-card/50 to-background\"\n >\n <div className=\"flex items-center gap-2 text-muted-foreground mb-1\">\n {item.icon}\n <span className=\"text-xs font-medium\">{item.label}</span>\n </div>\n <p className=\"font-bold text-lg\">{item.value}</p>\n </div>\n ))}\n </div>\n\n {/* Entity Types */}\n <PageSection\n title=\"Included Entity Types\"\n description=\"Data types that will be exported\"\n >\n <div className=\"flex flex-wrap gap-2\">\n {template.entityTypes.map((entity) => (\n <span\n key={entity}\n className=\"inline-flex items-center gap-2 px-3 py-2 rounded-lg text-sm font-medium border-2 border-border/50 bg-muted/30\"\n >\n {entity}\n </span>\n ))}\n </div>\n </PageSection>\n\n {/* Actions */}\n <div className=\"flex flex-col sm:flex-row gap-3 pt-2\">\n <button\n onClick={handleUseTemplate}\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 <Play size={18} />\n Use Template\n </button>\n {!template.isDefault && (\n <button\n onClick={() => setShowDeleteConfirm(true)}\n disabled={deleting}\n className=\"inline-flex items-center justify-center gap-2 px-6 py-3 border-2 border-status-error-bg/50 text-status-error-text rounded-lg hover:bg-status-error-bg-subtle transition-all duration-200 font-medium disabled:opacity-50\"\n >\n {deleting ? (\n <Loader2 size={18} className=\"animate-spin\" />\n ) : (\n <Trash2 size={18} />\n )}\n Delete Template\n </button>\n )}\n </div>\n\n {showDeleteConfirm && (\n <div\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby=\"template-delete-title\"\n className=\"fixed inset-0 z-50 flex items-center justify-center bg-background/80 backdrop-blur-sm p-4\"\n >\n <div className=\"w-full max-w-md rounded-xl border-2 border-border bg-card p-6 shadow-xl\">\n <h2 id=\"template-delete-title\" className=\"text-lg font-bold\">\n Delete template?\n </h2>\n <p className=\"mt-2 text-sm text-muted-foreground\">\n This removes the saved export configuration. Existing export jobs\n are not deleted.\n </p>\n <div className=\"mt-6 flex flex-col-reverse sm:flex-row sm:justify-end gap-3\">\n <button\n type=\"button\"\n onClick={() => setShowDeleteConfirm(false)}\n className=\"px-4 py-2 rounded-lg border-2 border-border hover:bg-accent transition-colors font-medium\"\n >\n Keep Template\n </button>\n <button\n type=\"button\"\n onClick={handleDelete}\n disabled={deleting}\n className=\"inline-flex items-center justify-center gap-2 px-4 py-2 rounded-lg bg-destructive text-destructive-foreground hover:bg-destructive/90 transition-colors font-medium disabled:opacity-50\"\n >\n {deleting ? (\n <Loader2 size={16} className=\"animate-spin\" />\n ) : null}\n Delete Template\n </button>\n </div>\n </div>\n </div>\n )}\n </PageLayout>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"TemplateDetailPage.js","names":[],"sources":["../../../src/export/pages/TemplateDetailPage.tsx"],"sourcesContent":["import { useParams } from \"react-router-dom\";\nimport { useState } from \"react\";\nimport {\n ArrowLeft,\n FileBox,\n Download,\n Play,\n Trash2,\n AlertCircle,\n Clock,\n FileText,\n HardDrive,\n Loader2,\n} from \"lucide-react\";\nimport { useExport } from \"../providers/ExportProvider\";\nimport {\n useExportTemplate,\n useDeleteExportTemplate,\n} from \"../hooks/useExportQueries\";\nimport {\n getFormatDisplayName,\n getArchiveFormatDisplayName,\n} from \"../constants/enums\";\nimport { PageLayout, PageSection } from \"../components/PageLayout\";\nimport { nativeImpact, nativeNotify } from \"../../utils/nativeBridge\";\n\n/**\n * Helper to join paths correctly\n */\nconst joinPath = (base: string, path: string): string => {\n const cleanBase = base.endsWith(\"/\") ? base.slice(0, -1) : base;\n const cleanPath = path.startsWith(\"/\") ? path : `/${path}`;\n return cleanBase + cleanPath;\n};\n\n/**\n * Template Detail Page\n * View template details and use it to create a new export.\n * Fetches template from the backend via useExportTemplate hook.\n */\nexport function TemplateDetailPage() {\n const { templateId } = useParams<{ templateId: string }>();\n const { basePath = \"/\", navigate } = useExport();\n const [showDeleteConfirm, setShowDeleteConfirm] = useState(false);\n\n const { data: template, isLoading } = useExportTemplate(templateId);\n const { deleteTemplate, isPending: deleting } = useDeleteExportTemplate();\n\n // Loading\n if (isLoading) {\n return (\n <div className=\"flex flex-col items-center justify-center py-20\">\n <Loader2 size={48} className=\"animate-spin text-primary\" />\n <span className=\"mt-6 text-sm font-medium text-muted-foreground\">\n Loading template details…\n </span>\n </div>\n );\n }\n\n if (!template) {\n return (\n <PageLayout showHeader={false}>\n <div className=\"flex items-center gap-3 mb-6\">\n <button\n type=\"button\"\n onClick={() => navigate?.(joinPath(basePath, \"templates\"))}\n className=\"p-2.5 hover:bg-accent rounded-lg transition-all duration-200\"\n >\n <ArrowLeft size={20} />\n </button>\n <h1 className=\"text-xl font-bold\">Template Not Found</h1>\n </div>\n <div className=\"border-2 border-border-default rounded-xl bg-status-error-bg-subtle p-12 text-center\">\n <AlertCircle\n size={48}\n className=\"text-status-error-text mx-auto mb-4\"\n />\n <h3 className=\"text-lg font-bold text-status-error-text mb-2\">\n Template Not Found\n </h3>\n <p className=\"text-status-error-text mb-6\">\n The template you are looking for does not exist.\n </p>\n <button\n type=\"button\"\n onClick={() => navigate?.(joinPath(basePath, \"templates\"))}\n className=\"inline-flex items-center gap-2 px-6 py-3 bg-primary text-primary-foreground rounded-lg hover:bg-primary/90 transition-colors font-medium\"\n >\n <ArrowLeft size={18} />\n Back to Templates\n </button>\n </div>\n </PageLayout>\n );\n }\n\n const handleUseTemplate = () => {\n // Navigate to new export page pre-selected with this template\n navigate?.(joinPath(basePath, `new?templateId=${templateId}`));\n };\n\n const handleDelete = async () => {\n if (!templateId) return;\n nativeImpact(\"medium\");\n try {\n await deleteTemplate(templateId);\n nativeNotify(\"success\");\n navigate?.(joinPath(basePath, \"templates\"));\n } catch {\n nativeNotify(\"error\");\n }\n };\n\n return (\n <PageLayout showHeader={false}>\n {/* Header */}\n <div className=\"relative overflow-hidden rounded-xl bg-gradient-to-br from-primary/5 via-primary/3 to-background border border-border/50 p-6 shadow-sm\">\n <div className=\"relative z-10 flex items-center gap-4\">\n <button\n type=\"button\"\n onClick={() => navigate?.(joinPath(basePath, \"templates\"))}\n className=\"p-2.5 hover:bg-accent rounded-lg transition-all duration-200\"\n >\n <ArrowLeft size={20} />\n </button>\n <div className=\"flex items-center gap-3 flex-1\">\n <div className=\"p-2.5 rounded-lg bg-primary/10\">\n <FileBox size={24} className=\"text-primary\" />\n </div>\n <div className=\"flex-1 min-w-0\">\n <h1 className=\"text-xl sm:text-2xl font-bold truncate\">\n {template.name}\n </h1>\n <p className=\"text-sm text-muted-foreground mt-1\">\n {template.isDefault ? \"Default template\" : \"Custom template\"}\n </p>\n </div>\n </div>\n </div>\n </div>\n\n {/* Description */}\n {template.description && (\n <div className=\"border-2 border-border/50 rounded-xl p-5\">\n <p className=\"text-sm text-muted-foreground\">\n {template.description}\n </p>\n </div>\n )}\n\n {/* Info Grid */}\n <div className=\"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4\">\n {[\n {\n icon: <FileText size={18} />,\n label: \"Format\",\n value: getFormatDisplayName(template.format),\n },\n {\n icon: <HardDrive size={18} />,\n label: \"Archive\",\n // Backend template doesn't carry archiveFormat, default to ZIP\n value: getArchiveFormatDisplayName(\"ZIP\"),\n },\n {\n icon: <Download size={18} />,\n label: \"Entity Types\",\n value: `${template.entityTypes.length} type${template.entityTypes.length !== 1 ? \"s\" : \"\"}`,\n },\n {\n icon: <Clock size={18} />,\n label: \"Last Updated\",\n value: new Date(template.updatedAt).toLocaleDateString(),\n },\n ].map((item) => (\n <div\n key={item.label}\n className=\"border-2 border-border/50 rounded-xl p-4 bg-gradient-to-br from-card/50 to-background\"\n >\n <div className=\"flex items-center gap-2 text-muted-foreground mb-1\">\n {item.icon}\n <span className=\"text-xs font-medium\">{item.label}</span>\n </div>\n <p className=\"font-bold text-lg\">{item.value}</p>\n </div>\n ))}\n </div>\n\n {/* Entity Types */}\n <PageSection\n title=\"Included Entity Types\"\n description=\"Data types that will be exported\"\n >\n <div className=\"flex flex-wrap gap-2\">\n {template.entityTypes.map((entity) => (\n <span\n key={entity}\n className=\"inline-flex items-center gap-2 px-3 py-2 rounded-lg text-sm font-medium border-2 border-border/50 bg-muted/30\"\n >\n {entity}\n </span>\n ))}\n </div>\n </PageSection>\n\n {/* Actions */}\n <div className=\"flex flex-col sm:flex-row gap-3 pt-2\">\n <button\n type=\"button\"\n onClick={handleUseTemplate}\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 <Play size={18} />\n Use Template\n </button>\n {!template.isDefault && (\n <button\n type=\"button\"\n onClick={() => setShowDeleteConfirm(true)}\n disabled={deleting}\n className=\"inline-flex items-center justify-center gap-2 px-6 py-3 border-2 border-status-error-bg/50 text-status-error-text rounded-lg hover:bg-status-error-bg-subtle transition-all duration-200 font-medium disabled:opacity-50\"\n >\n {deleting ? (\n <Loader2 size={18} className=\"animate-spin\" />\n ) : (\n <Trash2 size={18} />\n )}\n Delete Template\n </button>\n )}\n </div>\n\n {showDeleteConfirm && (\n <div\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby=\"template-delete-title\"\n className=\"fixed inset-0 z-50 flex items-center justify-center bg-background/80 backdrop-blur-sm p-4\"\n >\n <div className=\"w-full max-w-md rounded-xl border-2 border-border bg-card p-6 shadow-xl\">\n <h2 id=\"template-delete-title\" className=\"text-lg font-bold\">\n Delete template?\n </h2>\n <p className=\"mt-2 text-sm text-muted-foreground\">\n This removes the saved export configuration. Existing export jobs\n are not deleted.\n </p>\n <div className=\"mt-6 flex flex-col-reverse sm:flex-row sm:justify-end gap-3\">\n <button\n type=\"button\"\n onClick={() => setShowDeleteConfirm(false)}\n className=\"px-4 py-2 rounded-lg border-2 border-border hover:bg-accent transition-colors font-medium\"\n >\n Keep Template\n </button>\n <button\n type=\"button\"\n onClick={handleDelete}\n disabled={deleting}\n className=\"inline-flex items-center justify-center gap-2 px-4 py-2 rounded-lg bg-destructive text-destructive-foreground hover:bg-destructive/90 transition-colors font-medium disabled:opacity-50\"\n >\n {deleting ? (\n <Loader2 size={16} className=\"animate-spin\" />\n ) : null}\n Delete Template\n </button>\n </div>\n </div>\n </div>\n )}\n </PageLayout>\n );\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@burdenoff/microfe-export",
3
- "version": "2026.525.2",
3
+ "version": "2026.527.1",
4
4
  "description": "Burdenoff Export Microfrontend - Data export management interface",
5
5
  "type": "module",
6
6
  "files": [
@@ -1,2 +0,0 @@
1
-
2
- //# sourceMappingURL=main.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../../src/dev/main.tsx"],"names":[],"mappings":"AAQA,OAAO,cAAc,CAAC"}
@@ -1,31 +0,0 @@
1
- import { FC } from 'react';
2
- import { ExportRootProps } from './types';
3
-
4
- /**
5
- * Root component for the Export microfrontend.
6
- *
7
- * This is the main entry point that host applications import and render.
8
- * It sets up the necessary providers and renders the internal routing.
9
- * Automatically registers navigation items with the shell if registration functions are provided.
10
- *
11
- * @example
12
- * ```tsx
13
- * import { ExportRoot, type ExportRootProps } from '@burdenoff/micro-fe/export';
14
- *
15
- * function App() {
16
- * const props: ExportRootProps = {
17
- * basePath: '/export',
18
- * navigate: (path) => router.push(path),
19
- * currentUser: { id: '1', email: 'user@example.com', firstName: 'John', lastName: 'Doe' },
20
- * workspaceId: 'ws-123',
21
- * apiGatewayUrl: 'https://api.example.com',
22
- * authToken: 'token',
23
- * registerNavItems: (items) => { return () => {}; },
24
- * };
25
- *
26
- * return <ExportRoot {...props} />;
27
- * }
28
- * ```
29
- */
30
- export declare const ExportRoot: FC<ExportRootProps>;
31
- //# sourceMappingURL=ExportRoot.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ExportRoot.d.ts","sourceRoot":"","sources":["../../src/export/ExportRoot.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAMhC,OAAO,KAAK,EAAW,eAAe,EAAE,MAAM,SAAS,CAAC;AAGxD;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,eAAO,MAAM,UAAU,EAAE,EAAE,CAAC,eAAe,CAiG1C,CAAC"}
@@ -1,14 +0,0 @@
1
- /**
2
- * Internal router for the Export microfrontend.
3
- * This component handles routing within the microfrontend using React Router v7.
4
- *
5
- * Routes (relative to basePath, e.g., /export):
6
- * - / → Export dashboard page
7
- * - /new → Create new export job
8
- * - /history → Export history list
9
- * - /:jobId → Export job detail page
10
- * - /templates → Export templates list
11
- * - /templates/:templateId → Template detail page
12
- */
13
- export declare function ExportRoutes(): import("react/jsx-runtime").JSX.Element;
14
- //# sourceMappingURL=ExportRoutes.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ExportRoutes.d.ts","sourceRoot":"","sources":["../../src/export/ExportRoutes.tsx"],"names":[],"mappings":"AA8IA;;;;;;;;;;;GAWG;AACH,wBAAgB,YAAY,4CAoC3B"}
@@ -1,12 +0,0 @@
1
- interface ExportProgressBarProps {
2
- progress: number;
3
- className?: string;
4
- showLabel?: boolean;
5
- size?: "sm" | "md" | "lg";
6
- }
7
- /**
8
- * ExportProgressBar - Shows export progress percentage
9
- */
10
- export declare function ExportProgressBar({ progress, className, showLabel, size, }: ExportProgressBarProps): import("react/jsx-runtime").JSX.Element;
11
- export {};
12
- //# sourceMappingURL=ExportProgressBar.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ExportProgressBar.d.ts","sourceRoot":"","sources":["../../../src/export/components/ExportProgressBar.tsx"],"names":[],"mappings":"AAEA,UAAU,sBAAsB;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;CAC3B;AAQD;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,EAChC,QAAQ,EACR,SAAS,EACT,SAAgB,EAChB,IAAW,GACZ,EAAE,sBAAsB,2CAiCxB"}
@@ -1,12 +0,0 @@
1
- import { ExportJobStatus } from '../types';
2
-
3
- interface ExportStatusBadgeProps {
4
- status: ExportJobStatus;
5
- className?: string;
6
- }
7
- /**
8
- * ExportStatusBadge - Renders a colored badge for export job status
9
- */
10
- export declare function ExportStatusBadge({ status, className, }: ExportStatusBadgeProps): import("react/jsx-runtime").JSX.Element;
11
- export {};
12
- //# sourceMappingURL=ExportStatusBadge.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ExportStatusBadge.d.ts","sourceRoot":"","sources":["../../../src/export/components/ExportStatusBadge.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAGhD,UAAU,sBAAsB;IAC9B,MAAM,EAAE,eAAe,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAaD;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,EAChC,MAAM,EACN,SAAS,GACV,EAAE,sBAAsB,2CAiCxB"}
@@ -1,55 +0,0 @@
1
- import { ReactNode } from 'react';
2
-
3
- interface PageLayoutProps {
4
- children: ReactNode;
5
- /** Page title */
6
- title?: string;
7
- /** Page subtitle/description */
8
- subtitle?: string;
9
- /** Icon component to display next to title */
10
- icon?: ReactNode;
11
- /** Actions to display in header (buttons, etc.) */
12
- headerActions?: ReactNode;
13
- /** Additional header content below title */
14
- headerContent?: ReactNode;
15
- /** Maximum width of content: 'sm' | 'md' | 'lg' | 'xl' | '2xl' | '3xl' | 'full' */
16
- maxWidth?: "sm" | "md" | "lg" | "xl" | "2xl" | "3xl" | "full";
17
- /** Whether to show the header section */
18
- showHeader?: boolean;
19
- /** Additional CSS classes for the container */
20
- className?: string;
21
- /** Additional CSS classes for the content area */
22
- contentClassName?: string;
23
- }
24
- /**
25
- * PageLayout - A consistent page wrapper with responsive design
26
- *
27
- * Features:
28
- * - Proper max-width constraints
29
- * - Responsive padding
30
- * - Animated entrance
31
- * - Consistent header styling
32
- */
33
- export declare function PageLayout({ children, title, subtitle, icon, headerActions, headerContent, maxWidth, showHeader, className, contentClassName, }: PageLayoutProps): import("react/jsx-runtime").JSX.Element;
34
- /**
35
- * PageSection - A section within a page with consistent spacing
36
- */
37
- export declare function PageSection({ children, title, description, actions, className, }: {
38
- children: ReactNode;
39
- title?: string;
40
- description?: string;
41
- actions?: ReactNode;
42
- className?: string;
43
- }): import("react/jsx-runtime").JSX.Element;
44
- /**
45
- * EmptyState - A consistent empty state component
46
- */
47
- export declare function EmptyState({ icon, title, description, action, className, }: {
48
- icon?: ReactNode;
49
- title: string;
50
- description?: string;
51
- action?: ReactNode;
52
- className?: string;
53
- }): import("react/jsx-runtime").JSX.Element;
54
- export {};
55
- //# sourceMappingURL=PageLayout.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"PageLayout.d.ts","sourceRoot":"","sources":["../../../src/export/components/PageLayout.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAGvC,UAAU,eAAe;IACvB,QAAQ,EAAE,SAAS,CAAC;IACpB,iBAAiB;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,gCAAgC;IAChC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,8CAA8C;IAC9C,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,mDAAmD;IACnD,aAAa,CAAC,EAAE,SAAS,CAAC;IAC1B,4CAA4C;IAC5C,aAAa,CAAC,EAAE,SAAS,CAAC;IAC1B,mFAAmF;IACnF,QAAQ,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,KAAK,GAAG,KAAK,GAAG,MAAM,CAAC;IAC9D,yCAAyC;IACzC,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,+CAA+C;IAC/C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,kDAAkD;IAClD,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAYD;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CAAC,EACzB,QAAQ,EACR,KAAK,EACL,QAAQ,EACR,IAAI,EACJ,aAAa,EACb,aAAa,EACb,QAAe,EACf,UAAiB,EACjB,SAAS,EACT,gBAAgB,GACjB,EAAE,eAAe,2CAsEjB;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,EAC1B,QAAQ,EACR,KAAK,EACL,WAAW,EACX,OAAO,EACP,SAAS,GACV,EAAE;IACD,QAAQ,EAAE,SAAS,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,2CAmBA;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,EACzB,IAAI,EACJ,KAAK,EACL,WAAW,EACX,MAAM,EACN,SAAS,GACV,EAAE;IACD,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,2CAyBA"}
@@ -1,6 +0,0 @@
1
- /**
2
- * UI Component re-exports from @burdenoff/fe-libs
3
- * All styled components are imported from the shared fe-libs package
4
- */
5
- export { Button, Badge, Card, CardContent, Input, Skeleton, Separator, Select, SelectContent, SelectItem, SelectTrigger, SelectValue, Tabs, TabsList, TabsTrigger, TabsContent, } from '@burdenoff/fe-libs/ui';
6
- //# sourceMappingURL=ui.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ui.d.ts","sourceRoot":"","sources":["../../../src/export/components/ui.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EACL,MAAM,EACN,KAAK,EACL,IAAI,EACJ,WAAW,EACX,KAAK,EACL,QAAQ,EACR,SAAS,EACT,MAAM,EACN,aAAa,EACb,UAAU,EACV,aAAa,EACb,WAAW,EACX,IAAI,EACJ,QAAQ,EACR,WAAW,EACX,WAAW,GACZ,MAAM,uBAAuB,CAAC"}
@@ -1,79 +0,0 @@
1
- /**
2
- * GraphQL Enum Constants
3
- *
4
- * These constants mirror the GraphQL enum types but as JavaScript objects
5
- * that can be used as values (not just TypeScript types).
6
- */
7
- /**
8
- * Export Job Status - Lifecycle states for an export job
9
- *
10
- * Maps to GraphQL enum: ExportJobStatus
11
- */
12
- export declare const ExportJobStatus: {
13
- /** Job created, not yet queued */
14
- readonly CREATED: "CREATED";
15
- /** Job queued for processing */
16
- readonly QUEUED: "QUEUED";
17
- /** Job actively running */
18
- readonly RUNNING: "RUNNING";
19
- /** Job completed successfully */
20
- readonly COMPLETED: "COMPLETED";
21
- /** Job failed */
22
- readonly FAILED: "FAILED";
23
- /** Job cancelled by user */
24
- readonly CANCELLED: "CANCELLED";
25
- /** Job output has expired */
26
- readonly EXPIRED: "EXPIRED";
27
- /** Job has been deleted */
28
- readonly DELETED: "DELETED";
29
- };
30
- export type ExportJobStatusValue = (typeof ExportJobStatus)[keyof typeof ExportJobStatus];
31
- /**
32
- * Export Format - Output file format
33
- * Backend only supports JSON and CSV.
34
- *
35
- * Maps to GraphQL enum: ExportFormat
36
- */
37
- export declare const ExportFormat: {
38
- /** Comma-separated values */
39
- readonly CSV: "CSV";
40
- /** JavaScript Object Notation */
41
- readonly JSON: "JSON";
42
- };
43
- export type ExportFormatValue = (typeof ExportFormat)[keyof typeof ExportFormat];
44
- /**
45
- * Export Archive Format - How parts are archived
46
- * Backend only supports ZIP.
47
- *
48
- * Maps to GraphQL enum: ExportArchiveFormat
49
- */
50
- export declare const ExportArchiveFormat: {
51
- /** ZIP archive */
52
- readonly ZIP: "ZIP";
53
- };
54
- export type ExportArchiveFormatValue = (typeof ExportArchiveFormat)[keyof typeof ExportArchiveFormat];
55
- /**
56
- * Helper: Get status display name
57
- */
58
- export declare const getStatusDisplayName: (status: string) => string;
59
- /**
60
- * Helper: Get status color class
61
- */
62
- export declare const getStatusColor: (status: string) => string;
63
- /**
64
- * Helper: Get format display name
65
- */
66
- export declare const getFormatDisplayName: (format: string) => string;
67
- /**
68
- * Helper: Get archive format display name
69
- */
70
- export declare const getArchiveFormatDisplayName: (format: string) => string;
71
- /**
72
- * Helper: Get all export statuses as array
73
- */
74
- export declare const getAllStatuses: () => ("CREATED" | "QUEUED" | "RUNNING" | "COMPLETED" | "FAILED" | "CANCELLED" | "EXPIRED" | "DELETED")[];
75
- /**
76
- * Helper: Get all export formats as array
77
- */
78
- export declare const getAllFormats: () => ("CSV" | "JSON")[];
79
- //# sourceMappingURL=enums.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"enums.d.ts","sourceRoot":"","sources":["../../../src/export/constants/enums.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;;;GAIG;AACH,eAAO,MAAM,eAAe;IAC1B,kCAAkC;;IAElC,gCAAgC;;IAEhC,2BAA2B;;IAE3B,iCAAiC;;IAEjC,iBAAiB;;IAEjB,4BAA4B;;IAE5B,6BAA6B;;IAE7B,2BAA2B;;CAEnB,CAAC;AAEX,MAAM,MAAM,oBAAoB,GAC9B,CAAC,OAAO,eAAe,CAAC,CAAC,MAAM,OAAO,eAAe,CAAC,CAAC;AAEzD;;;;;GAKG;AACH,eAAO,MAAM,YAAY;IACvB,6BAA6B;;IAE7B,iCAAiC;;CAEzB,CAAC;AAEX,MAAM,MAAM,iBAAiB,GAC3B,CAAC,OAAO,YAAY,CAAC,CAAC,MAAM,OAAO,YAAY,CAAC,CAAC;AAEnD;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB;IAC9B,kBAAkB;;CAEV,CAAC;AAEX,MAAM,MAAM,wBAAwB,GAClC,CAAC,OAAO,mBAAmB,CAAC,CAAC,MAAM,OAAO,mBAAmB,CAAC,CAAC;AAEjE;;GAEG;AACH,eAAO,MAAM,oBAAoB,GAAI,QAAQ,MAAM,KAAG,MAYrD,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,cAAc,GAAI,QAAQ,MAAM,KAAG,MAY/C,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,oBAAoB,GAAI,QAAQ,MAAM,KAAG,MAMrD,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,2BAA2B,GAAI,QAAQ,MAAM,KAAG,MAK5D,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,cAAc,2GAAuC,CAAC;AAEnE;;GAEG;AACH,eAAO,MAAM,aAAa,0BAAoC,CAAC"}
@@ -1,7 +0,0 @@
1
- /**
2
- * Export Module Constants
3
- *
4
- * Centralized exports for all constants used in the export module
5
- */
6
- export * from './enums';
7
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/export/constants/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,cAAc,SAAS,CAAC"}