@postxl/generators 1.13.0 → 1.15.0

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 (117) hide show
  1. package/dist/backend-authentication/generators/authentication-service.generator.js +1 -1
  2. package/dist/backend-core/backend.generator.js +0 -4
  3. package/dist/backend-core/backend.generator.js.map +1 -1
  4. package/dist/backend-core/modules/backend-module-xlport.generator.js +1 -1
  5. package/dist/backend-excel-io/excel-io.generator.d.ts +19 -0
  6. package/dist/backend-excel-io/excel-io.generator.js +106 -0
  7. package/dist/backend-excel-io/excel-io.generator.js.map +1 -0
  8. package/dist/backend-excel-io/generators/excel-io-service.generator.d.ts +9 -0
  9. package/dist/backend-excel-io/generators/excel-io-service.generator.js +680 -0
  10. package/dist/backend-excel-io/generators/excel-io-service.generator.js.map +1 -0
  11. package/dist/backend-excel-io/index.d.ts +2 -0
  12. package/dist/backend-excel-io/index.js +22 -0
  13. package/dist/backend-excel-io/index.js.map +1 -0
  14. package/dist/backend-excel-io/template/README.md +24 -0
  15. package/dist/backend-excel-io/template/excel-io.controller.ts +195 -0
  16. package/dist/backend-excel-io/template/excel-io.module.ts +17 -0
  17. package/dist/backend-import/generators/detect-delta/detect-delta-functions.generator.js +148 -13
  18. package/dist/backend-import/generators/detect-delta/detect-delta-functions.generator.js.map +1 -1
  19. package/dist/backend-import/generators/filter-error-rows.generator.d.ts +2 -0
  20. package/dist/backend-import/generators/filter-error-rows.generator.js +28 -0
  21. package/dist/backend-import/generators/filter-error-rows.generator.js.map +1 -0
  22. package/dist/backend-import/generators/import-service.generator.js +126 -2
  23. package/dist/backend-import/generators/import-service.generator.js.map +1 -1
  24. package/dist/backend-import/import.generator.js +2 -0
  25. package/dist/backend-import/import.generator.js.map +1 -1
  26. package/dist/backend-repositories/generators/model-repository.generator.js +17 -2
  27. package/dist/backend-repositories/generators/model-repository.generator.js.map +1 -1
  28. package/dist/backend-router-trpc/generators/app-routes.generator.js +5 -0
  29. package/dist/backend-router-trpc/generators/app-routes.generator.js.map +1 -1
  30. package/dist/backend-router-trpc/generators/excel-io-route.generator.d.ts +4 -0
  31. package/dist/backend-router-trpc/generators/excel-io-route.generator.js +35 -0
  32. package/dist/backend-router-trpc/generators/excel-io-route.generator.js.map +1 -0
  33. package/dist/backend-router-trpc/generators/trpc-plugin.generator.js +6 -0
  34. package/dist/backend-router-trpc/generators/trpc-plugin.generator.js.map +1 -1
  35. package/dist/backend-router-trpc/generators/trpc-router-module.generator.js +8 -1
  36. package/dist/backend-router-trpc/generators/trpc-router-module.generator.js.map +1 -1
  37. package/dist/backend-router-trpc/generators/trpc-shared.generator.js +9 -0
  38. package/dist/backend-router-trpc/generators/trpc-shared.generator.js.map +1 -1
  39. package/dist/backend-router-trpc/router-trpc.generator.d.ts +2 -1
  40. package/dist/backend-router-trpc/router-trpc.generator.js +4 -0
  41. package/dist/backend-router-trpc/router-trpc.generator.js.map +1 -1
  42. package/dist/backend-update/model-update-service.generator.js +54 -0
  43. package/dist/backend-update/model-update-service.generator.js.map +1 -1
  44. package/dist/backend-update/update-actions.decoders.d.ts +2 -0
  45. package/dist/backend-update/update-actions.decoders.js +2 -0
  46. package/dist/backend-update/update-actions.decoders.js.map +1 -1
  47. package/dist/backend-update/update.generator.js +6 -0
  48. package/dist/backend-update/update.generator.js.map +1 -1
  49. package/dist/base/base.generator.js +0 -4
  50. package/dist/base/base.generator.js.map +1 -1
  51. package/dist/decoders/datamodel-decoder.generator.js +91 -1
  52. package/dist/decoders/datamodel-decoder.generator.js.map +1 -1
  53. package/dist/decoders/decoders.generator.d.ts +9 -0
  54. package/dist/decoders/decoders.generator.js +15 -0
  55. package/dist/decoders/decoders.generator.js.map +1 -1
  56. package/dist/decoders/discriminated-union.decoder.generator.js +4 -3
  57. package/dist/decoders/discriminated-union.decoder.generator.js.map +1 -1
  58. package/dist/devops/devops.generator.d.ts +5 -1
  59. package/dist/devops/devops.generator.js +5 -4
  60. package/dist/devops/devops.generator.js.map +1 -1
  61. package/dist/devops/generators/docker-compose-yml.generator.d.ts +1 -1
  62. package/dist/devops/generators/docker-compose-yml.generator.js +16 -1
  63. package/dist/devops/generators/docker-compose-yml.generator.js.map +1 -1
  64. package/dist/e2e/template/e2e/specs/example.spec.ts-snapshots/Navigate-to-homepage-and-take-snapshot-1-chromium-linux.png +0 -0
  65. package/dist/frontend-actions/generators/filter-utils.generator.js +1 -1
  66. package/dist/frontend-admin/admin.generator.d.ts +2 -0
  67. package/dist/frontend-admin/admin.generator.js +28 -0
  68. package/dist/frontend-admin/admin.generator.js.map +1 -1
  69. package/dist/frontend-admin/generators/admin-global-actions.generator.js +78 -0
  70. package/dist/frontend-admin/generators/admin-global-actions.generator.js.map +1 -1
  71. package/dist/frontend-admin/generators/admin-overview-page.generator.js +21 -1
  72. package/dist/frontend-admin/generators/admin-overview-page.generator.js.map +1 -1
  73. package/dist/frontend-admin/generators/admin-sidebar.generator.js +20 -0
  74. package/dist/frontend-admin/generators/admin-sidebar.generator.js.map +1 -1
  75. package/dist/frontend-admin/generators/excel-io-page.generator.d.ts +4 -0
  76. package/dist/frontend-admin/generators/excel-io-page.generator.js +258 -0
  77. package/dist/frontend-admin/generators/excel-io-page.generator.js.map +1 -0
  78. package/dist/frontend-admin/generators/import-review-page-result-stage.generator.d.ts +1 -0
  79. package/dist/frontend-admin/generators/import-review-page-result-stage.generator.js +104 -0
  80. package/dist/frontend-admin/generators/import-review-page-result-stage.generator.js.map +1 -0
  81. package/dist/frontend-admin/generators/import-review-page-review-stage.generator.d.ts +1 -0
  82. package/dist/frontend-admin/generators/import-review-page-review-stage.generator.js +1031 -0
  83. package/dist/frontend-admin/generators/import-review-page-review-stage.generator.js.map +1 -0
  84. package/dist/frontend-admin/generators/import-review-page-upload-stage.generator.d.ts +1 -0
  85. package/dist/frontend-admin/generators/import-review-page-upload-stage.generator.js +77 -0
  86. package/dist/frontend-admin/generators/import-review-page-upload-stage.generator.js.map +1 -0
  87. package/dist/frontend-admin/generators/import-review-page.generator.d.ts +7 -0
  88. package/dist/frontend-admin/generators/import-review-page.generator.js +180 -0
  89. package/dist/frontend-admin/generators/import-review-page.generator.js.map +1 -0
  90. package/dist/frontend-admin/generators/model-admin-page.generator.js +60 -56
  91. package/dist/frontend-admin/generators/model-admin-page.generator.js.map +1 -1
  92. package/dist/frontend-admin/utils.js +25 -33
  93. package/dist/frontend-admin/utils.js.map +1 -1
  94. package/dist/frontend-core/frontend.generator.js +1 -2
  95. package/dist/frontend-core/frontend.generator.js.map +1 -1
  96. package/dist/frontend-core/template/src/components/admin/excel-io-actions.tsx +64 -0
  97. package/dist/frontend-core/template/src/components/admin/table-view-panel.tsx +41 -3
  98. package/dist/frontend-core/template/src/hooks/use-excel-io.ts +137 -0
  99. package/dist/frontend-core/template/src/hooks/use-import-review.ts +143 -0
  100. package/dist/frontend-core/template/src/lib/excel-download.ts +28 -0
  101. package/dist/frontend-core/types/hook.d.ts +1 -1
  102. package/dist/frontend-tables/generators/model-table.generator.js +21 -13
  103. package/dist/frontend-tables/generators/model-table.generator.js.map +1 -1
  104. package/dist/frontend-trpc-client/generators/model-hook.generator.js +4 -0
  105. package/dist/frontend-trpc-client/generators/model-hook.generator.js.map +1 -1
  106. package/dist/frontend-trpc-client/trpc-client.generator.d.ts +4 -0
  107. package/dist/frontend-trpc-client/trpc-client.generator.js +1 -0
  108. package/dist/frontend-trpc-client/trpc-client.generator.js.map +1 -1
  109. package/dist/generators.js +2 -0
  110. package/dist/generators.js.map +1 -1
  111. package/dist/index.d.ts +1 -0
  112. package/dist/index.js +5 -2
  113. package/dist/index.js.map +1 -1
  114. package/dist/seed-data/seed-data.generator.d.ts +3 -0
  115. package/dist/seed-data/seed-data.generator.js +45 -1
  116. package/dist/seed-data/seed-data.generator.js.map +1 -1
  117. package/package.json +3 -3
@@ -0,0 +1 @@
1
+ {"version":3,"file":"import-review-page-review-stage.generator.js","sourceRoot":"","sources":["../../../src/frontend-admin/generators/import-review-page-review-stage.generator.ts"],"names":[],"mappings":";;AAAA,0EAkgCC;AAlgCD,SAAgB,+BAA+B;IAC7C,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAggCR,CAAA;AACD,CAAC"}
@@ -0,0 +1 @@
1
+ export declare function generateImportReviewUploadStage(): string;
@@ -0,0 +1,77 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.generateImportReviewUploadStage = generateImportReviewUploadStage;
4
+ function generateImportReviewUploadStage() {
5
+ return `
6
+ function UploadStage({
7
+ isLoading,
8
+ onUpload,
9
+ }: Readonly<{
10
+ isLoading: boolean
11
+ onUpload: (file: File, options: { includeDetailedUnchangedRecords: boolean }) => Promise<void>
12
+ }>) {
13
+ const [selectedFile, setSelectedFile] = useState<File | null>(null)
14
+ const [includeDetailedUnchangedRecords, setIncludeDetailedUnchangedRecords] = useState(false)
15
+
16
+ return (
17
+ <Card>
18
+ <CardHeader>
19
+ <CardTitle>Upload Excel File</CardTitle>
20
+ </CardHeader>
21
+ <CardContent className="space-y-4">
22
+ <div className="space-y-2">
23
+ <Label htmlFor="import-review-file">Select an .xlsx or .xls file to preview before importing</Label>
24
+ <Input
25
+ id="import-review-file"
26
+ type="file"
27
+ accept=".xlsx,.xls"
28
+ disabled={isLoading}
29
+ onChange={(event) => setSelectedFile(event.target.files?.[0] ?? null)}
30
+ />
31
+ {selectedFile && <p className="text-sm text-muted-foreground">Selected file: {selectedFile.name}</p>}
32
+ </div>
33
+
34
+ <div className="flex items-center gap-2">
35
+ <Checkbox
36
+ id="detailed-unchanged"
37
+ checked={includeDetailedUnchangedRecords}
38
+ checkIcon="check"
39
+ onChange={(event: React.ChangeEvent<HTMLInputElement>) =>
40
+ setIncludeDetailedUnchangedRecords(event.target.checked)
41
+ }
42
+ />
43
+ <Label htmlFor="detailed-unchanged">Include detailed unchanged records</Label>
44
+ <TooltipProvider delayDuration={150}>
45
+ <Tooltip>
46
+ <TooltipTrigger asChild>
47
+ <button
48
+ type="button"
49
+ aria-label="Info about detailed unchanged records"
50
+ className="inline-flex h-5 w-5 items-center justify-center rounded-full border text-xs text-muted-foreground"
51
+ >
52
+ i
53
+ </button>
54
+ </TooltipTrigger>
55
+ <TooltipContent>
56
+ <p>On large datasets, including unchanged row details may take longer.</p>
57
+ </TooltipContent>
58
+ </Tooltip>
59
+ </TooltipProvider>
60
+ </div>
61
+
62
+ <div className="flex gap-3">
63
+ <Button
64
+ disabled={isLoading || !selectedFile}
65
+ onClick={() => selectedFile && void onUpload(selectedFile, { includeDetailedUnchangedRecords })}
66
+ >
67
+ {isLoading ? 'Building preview...' : 'Create Preview'}
68
+ </Button>
69
+ </div>
70
+ </CardContent>
71
+ </Card>
72
+ )
73
+ }
74
+
75
+ `;
76
+ }
77
+ //# sourceMappingURL=import-review-page-upload-stage.generator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"import-review-page-upload-stage.generator.js","sourceRoot":"","sources":["../../../src/frontend-admin/generators/import-review-page-upload-stage.generator.ts"],"names":[],"mappings":";;AAAA,0EAwEC;AAxED,SAAgB,+BAA+B;IAC7C,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAsER,CAAA;AACD,CAAC"}
@@ -0,0 +1,7 @@
1
+ import { ContextResult } from '../admin.generator';
2
+ /**
3
+ * Generator function that generates the Import Review admin page.
4
+ */
5
+ export declare function generateImportReviewPage({ context }: {
6
+ context: ContextResult;
7
+ }): string;
@@ -0,0 +1,180 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.generateImportReviewPage = generateImportReviewPage;
4
+ const import_review_page_result_stage_generator_1 = require("./import-review-page-result-stage.generator");
5
+ const import_review_page_review_stage_generator_1 = require("./import-review-page-review-stage.generator");
6
+ const import_review_page_upload_stage_generator_1 = require("./import-review-page-upload-stage.generator");
7
+ /**
8
+ * Generator function that generates the Import Review admin page.
9
+ */
10
+ function generateImportReviewPage({ context }) {
11
+ const models = [...context.models.values()].sort((a, b) => a.userFriendlyName.localeCompare(b.userFriendlyName));
12
+ const modelSchemaMapEntries = models
13
+ .map((model) => ` ${model._conjugated.camelCasePlural}: '${model.databaseSchema}',`)
14
+ .join('\n');
15
+ const modelLabelMapEntries = models
16
+ .map((model) => ` ${model._conjugated.camelCasePlural}: '${model.userFriendlyName.replaceAll("'", "\\'")}',`)
17
+ .join('\n');
18
+ const modelFieldOrderEntries = models
19
+ .map((model) => {
20
+ const fields = Array.from(model.fields.values())
21
+ .map((field) => `'${field.name}'`)
22
+ .join(', ');
23
+ return ` ${model._conjugated.camelCasePlural}: [${fields}],`;
24
+ })
25
+ .join('\n');
26
+ const schemaOrderEntries = [...new Set(models.map((model) => model.databaseSchema))]
27
+ .sort((a, b) => a.localeCompare(b))
28
+ .map((schema) => `'${schema}'`)
29
+ .join(', ');
30
+ return `
31
+ import { AdminSidebar } from '@admin/admin-sidebar'
32
+
33
+ import type { ColumnDef } from '@tanstack/react-table'
34
+ import { useEffect, useMemo, useState } from 'react'
35
+ import { AlertTriangleIcon, MinusIcon, PencilIcon, PlusIcon, Trash2Icon } from 'lucide-react'
36
+
37
+ import type {
38
+ ImportExecutionSummary,
39
+ ImportPreviewItem,
40
+ ImportPreviewModelSummary,
41
+ ImportPreviewResponse,
42
+ SelectedDeltaIndicesByModel,
43
+ } from '@hooks/use-import-review'
44
+ import { useImportReview } from '@hooks/use-import-review'
45
+ import {
46
+ Alert,
47
+ AlertDialog,
48
+ AlertDialogAction,
49
+ AlertDialogCancel,
50
+ AlertDialogContent,
51
+ AlertDialogDescription,
52
+ AlertDialogFooter,
53
+ AlertDialogHeader,
54
+ AlertDialogTitle,
55
+ AlertDescription,
56
+ Badge,
57
+ Button,
58
+ Card,
59
+ CardContent,
60
+ CardHeader,
61
+ CardTitle,
62
+ Checkbox,
63
+ DataGrid,
64
+ Input,
65
+ Label,
66
+ SidebarInset,
67
+ SidebarProvider,
68
+ Tooltip,
69
+ TooltipContent,
70
+ TooltipProvider,
71
+ TooltipTrigger,
72
+ cn,
73
+ useDataGrid,
74
+ } from '@postxl/ui-components'
75
+
76
+ const MODEL_SCHEMA_MAP: Record<string, string> = {
77
+ ${modelSchemaMapEntries}
78
+ }
79
+
80
+ const MODEL_LABEL_MAP: Record<string, string> = {
81
+ ${modelLabelMapEntries}
82
+ }
83
+
84
+ const MODEL_FIELD_ORDER: Record<string, string[]> = {
85
+ ${modelFieldOrderEntries}
86
+ }
87
+
88
+ const SCHEMA_ORDER: string[] = [${schemaOrderEntries}]
89
+
90
+ const TYPE_ORDER: ImportPreviewItem['type'][] = ['errors', 'delete', 'update', 'create', 'unchanged']
91
+
92
+ const TYPE_BADGE_CLASSES: Record<ImportPreviewItem['type'], string> = {
93
+ create: 'text-green-700 border-green-300 dark:text-green-400 dark:border-green-700',
94
+ update: 'text-blue-700 border-blue-300 dark:text-blue-400 dark:border-blue-700',
95
+ delete: 'text-red-700 border-red-300 dark:text-red-400 dark:border-red-700',
96
+ unchanged: 'text-muted-foreground border-border',
97
+ errors: 'text-red-700 border-red-300 dark:text-red-400 dark:border-red-700',
98
+ }
99
+
100
+ const EXECUTABLE_TYPES = new Set<ImportPreviewItem['type']>(['create', 'update', 'delete'])
101
+
102
+ export default function ImportReviewPage() {
103
+ const { stage, preview, executionResult, error, isLoading, uploadAndPreview, execute, reset } = useImportReview()
104
+
105
+ const showAdminSidebar = stage === 'upload' || stage === 'previewing' || stage === 'result'
106
+
107
+ return (
108
+ <SidebarProvider defaultOpen>
109
+ {showAdminSidebar && <AdminSidebar />}
110
+
111
+ <SidebarInset className="p-4">
112
+ <div className="mx-auto flex w-full max-w-[1400px] flex-col gap-4">
113
+ <PageHeader stage={stage} />
114
+
115
+ {error && (
116
+ <Alert variant="destructive">
117
+ <AlertDescription>{error}</AlertDescription>
118
+ </Alert>
119
+ )}
120
+
121
+ {(stage === 'upload' || stage === 'previewing') && (
122
+ <UploadStage isLoading={isLoading} onUpload={uploadAndPreview} />
123
+ )}
124
+
125
+ {stage === 'review' && preview && (
126
+ <ReviewStage preview={preview} isLoading={isLoading} onExecute={execute} onReset={reset} />
127
+ )}
128
+
129
+ {stage === 'executing' && (
130
+ <Card>
131
+ <CardContent className="py-8 text-center">
132
+ <p className="text-lg font-medium">Executing selected changes...</p>
133
+ <p className="mt-2 text-sm text-muted-foreground">Applying selected rows to the database.</p>
134
+ </CardContent>
135
+ </Card>
136
+ )}
137
+
138
+ {stage === 'result' && executionResult && <ResultStage result={executionResult} onReset={reset} />}
139
+ </div>
140
+ </SidebarInset>
141
+ </SidebarProvider>
142
+ )
143
+ }
144
+
145
+ function PageHeader({ stage }: Readonly<{ stage: 'upload' | 'previewing' | 'review' | 'executing' | 'result' }>) {
146
+ const currentStep = stage === 'upload' || stage === 'previewing' ? 1 : stage === 'review' || stage === 'executing' ? 2 : 3
147
+
148
+ return (
149
+ <div className="space-y-3">
150
+ <h1 className="text-3xl font-bold">Import Review</h1>
151
+ <p className="text-sm text-muted-foreground">
152
+ Upload an Excel file, review and select changes, then execute a controlled import.
153
+ </p>
154
+ <div className="grid grid-cols-3 gap-2">
155
+ <StepChip label="1. Upload" active={currentStep === 1} done={currentStep > 1} />
156
+ <StepChip label="2. Preview & Select" active={currentStep === 2} done={currentStep > 2} />
157
+ <StepChip label="3. Results" active={currentStep === 3} done={false} />
158
+ </div>
159
+ </div>
160
+ )
161
+ }
162
+
163
+ function StepChip({ label, active, done }: Readonly<{ label: string; active: boolean; done: boolean }>) {
164
+ const stateClass = done
165
+ ? 'border-green-300 bg-green-50 text-green-700 dark:border-green-800 dark:bg-green-950/40 dark:text-green-300'
166
+ : active
167
+ ? 'border-blue-300 bg-blue-50 text-blue-700 dark:border-blue-800 dark:bg-blue-950/40 dark:text-blue-300'
168
+ : 'border-border bg-background text-muted-foreground'
169
+
170
+ return <div className={cn('rounded border px-3 py-2 text-sm font-medium', stateClass)}>{label}</div>
171
+ }
172
+
173
+ ${(0, import_review_page_upload_stage_generator_1.generateImportReviewUploadStage)()}
174
+
175
+ ${(0, import_review_page_review_stage_generator_1.generateImportReviewReviewStage)()}
176
+
177
+ ${(0, import_review_page_result_stage_generator_1.generateImportReviewResultStage)()}
178
+ `;
179
+ }
180
+ //# sourceMappingURL=import-review-page.generator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"import-review-page.generator.js","sourceRoot":"","sources":["../../../src/frontend-admin/generators/import-review-page.generator.ts"],"names":[],"mappings":";;AASA,4DA8KC;AArLD,2GAA6F;AAC7F,2GAA6F;AAC7F,2GAA6F;AAE7F;;GAEG;AACH,SAAgB,wBAAwB,CAAC,EAAE,OAAO,EAA8B;IAC9E,MAAM,MAAM,GAAG,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,gBAAgB,CAAC,aAAa,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAA;IAEhH,MAAM,qBAAqB,GAAG,MAAM;SACjC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,KAAK,CAAC,WAAW,CAAC,eAAe,MAAM,KAAK,CAAC,cAAc,IAAI,CAAC;SACpF,IAAI,CAAC,IAAI,CAAC,CAAA;IAEb,MAAM,oBAAoB,GAAG,MAAM;SAChC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,KAAK,CAAC,WAAW,CAAC,eAAe,MAAM,KAAK,CAAC,gBAAgB,CAAC,UAAU,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC;SAC7G,IAAI,CAAC,IAAI,CAAC,CAAA;IAEb,MAAM,sBAAsB,GAAG,MAAM;SAClC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;QACb,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;aAC7C,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,KAAK,CAAC,IAAI,GAAG,CAAC;aACjC,IAAI,CAAC,IAAI,CAAC,CAAA;QACb,OAAO,KAAK,KAAK,CAAC,WAAW,CAAC,eAAe,MAAM,MAAM,IAAI,CAAA;IAC/D,CAAC,CAAC;SACD,IAAI,CAAC,IAAI,CAAC,CAAA;IAEb,MAAM,kBAAkB,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC,CAAC;SACjF,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;SAClC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,IAAI,MAAM,GAAG,CAAC;SAC9B,IAAI,CAAC,IAAI,CAAC,CAAA;IAEb,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA+CP,qBAAqB;;;;EAIrB,oBAAoB;;;;EAIpB,sBAAsB;;;kCAGU,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAqFlD,IAAA,2EAA+B,GAAE;;EAEjC,IAAA,2EAA+B,GAAE;;EAEjC,IAAA,2EAA+B,GAAE;CAClC,CAAA;AACD,CAAC"}
@@ -70,7 +70,7 @@ function generateModelAdminPage({ model, context, }) {
70
70
  })
71
71
  .addImport({
72
72
  from: Generator.toPackageName('@tanstack/react-router'),
73
- items: [Generator.toFunctionName('useNavigate')],
73
+ items: [Generator.toFunctionName('useNavigate'), Generator.toFunctionName('useSearch')],
74
74
  })
75
75
  .addImport({
76
76
  from: Generator.toBackendModuleLocation('@app-actions/command-palette-action'),
@@ -117,6 +117,7 @@ function generateModelAdminPage({ model, context, }) {
117
117
  imports
118
118
  //
119
119
  .addType(model.types.id)
120
+ .addImport({ from: Generator.toPackageName('react'), items: [Generator.toFunctionName('useRef')] })
120
121
  .addImport({ from: Generator.toPackageName('sonner'), items: [Generator.toFunctionName('toast')] })
121
122
  .addImport({ from: model.forms.createModal.location, items: [model.forms.createModal.name] });
122
123
  // In case the model does not provide any explicit label field, we generally use the id field as fallback.
@@ -171,22 +172,19 @@ import useLocalStorageState from 'use-local-storage-state'
171
172
  import { useAuth } from '@context-providers/auth-context-provider'
172
173
  ${imports.generate()}
173
174
 
174
- type CellSelection = {
175
- rowIndex: number
176
- columnId: string
177
- }
178
-
179
175
  const SIDEBAR_WIDTH_KEY = 'audit-log-sidebar-width'
180
176
 
181
- type ${model.admin.page.pageComponent.name}Props = {
182
- selectedKey?: string
183
- }
184
-
185
- export default function ${model.admin.page.pageComponent.name}({ selectedKey }: ${model.admin.page.pageComponent.name}Props) {
177
+ export default function ${model.admin.page.pageComponent.name}() {
186
178
  const navigate = useNavigate()
187
179
  const { viewerData } = useAuth()
188
180
  const currentUserId = viewerData?.user?.id
189
181
  const isAdmin = viewerData?.userRoles?.includes('admin') ?? false
182
+
183
+ const { selectedKey, focusedCell } = useSearch({
184
+ from: '/_auth-routes${model.admin.page.route}',
185
+ select: (search) => ({ selectedKey: search.selectedKey, focusedCell: search.focusedCell }),
186
+ })
187
+
190
188
  ${createModalHook}
191
189
  ${createModalIntentHook}
192
190
  const sidepanelOpen = useAiAssistantState((state) => state.open)
@@ -197,9 +195,6 @@ export default function ${model.admin.page.pageComponent.name}({ selectedKey }:
197
195
  defaultValue: 350,
198
196
  })
199
197
 
200
- // Track the currently focused cell for audit log filtering
201
- const [focusedCell, setFocusedCell] = useState<CellSelection | null>(null)
202
-
203
198
  // Track selected row IDs from checkbox selection
204
199
  const [selectedRowIds, setSelectedRowIds] = useState<string[]>([])
205
200
 
@@ -217,28 +212,22 @@ export default function ${model.admin.page.pageComponent.name}({ selectedKey }:
217
212
  hasNextPage,
218
213
  fetchNextPage,
219
214
  total,
220
- ${model.isReadonly ? '' : `${model.itemsHook.updateField.name}: updateFieldMutation, ${model.itemsHook.deleteMany.name}: deleteManyMutation,`}
215
+ ${model.isReadonly ? '' : `${model.itemsHook.updateField.name}: updateFieldMutation, ${model.itemsHook.updateFieldMany.name}: updateFieldManyMutation, ${model.itemsHook.deleteMany.name}: deleteManyMutation,`}
221
216
  } = ${model.itemsHook.name}({ filters, sort: sortState })
222
217
 
223
218
  // Queries for related models' maps used by the table (passed as separate props)
224
219
  ${relatedModels.map((rm) => rm.mapDefinition).join('\n ')}
225
220
 
226
221
 
227
- // Get the selected entity ID based on focused cell
228
- const selectedEntityId = useMemo(() => {
229
- if (!filteredDataList || !focusedCell || focusedCell.rowIndex < 0 || focusedCell.rowIndex >= filteredDataList.length) {
230
- return null
231
- }
232
- const row = filteredDataList[focusedCell.rowIndex]
233
- return row?.id ?? null
234
- }, [focusedCell, filteredDataList])
222
+ // The selected entity ID comes from the URL selectedKey (which is the entity's id)
223
+ const selectedEntityId = selectedKey ?? null
235
224
 
236
- // Get the selected field name based on focused cell
225
+ // Get the selected field name based on focused cell (columnId from search params)
237
226
  const selectedField = useMemo(() => {
238
- if (!focusedCell || focusedCell.columnId === 'select' || focusedCell.columnId === 'actions') {
227
+ if (!focusedCell || focusedCell === 'select' || focusedCell === 'actions') {
239
228
  return null
240
229
  }
241
- return focusedCell.columnId
230
+ return focusedCell
242
231
  }, [focusedCell])
243
232
 
244
233
  ${showComments
@@ -253,35 +242,25 @@ export default function ${model.admin.page.pageComponent.name}({ selectedKey }:
253
242
  )
254
243
  `
255
244
  : ''}
256
- // Callback when cell focus changes in the table
257
- const handleCellChange = useCallback((args: { rowIndex: number; columnId: string }) => {
258
- setFocusedCell({ rowIndex: args.rowIndex, columnId: args.columnId })
259
- // Clear checkbox selection when focusing a cell
260
- setSelectedRowIds([])
261
- }, [])
262
-
263
245
  // Callback when row selection changes (checkbox)
264
246
  const handleRowSelectionChange = useCallback((rowIds: string[]) => {
265
247
  setSelectedRowIds(rowIds)
266
248
  // Clear cell selection when using checkbox selection
267
249
  if (rowIds.length > 0) {
268
- setFocusedCell(null)
250
+ void navigate({ to: '${model.admin.page.route}', search: { selectedKey: undefined, focusedCell: undefined } })
269
251
  }
270
- }, [])
252
+ }, [navigate])
271
253
 
272
254
  // Clear field filter (go up to entity level)
273
255
  const handleClearField = useCallback(() => {
274
- if (focusedCell) {
275
- // Keep the entity selected but clear the field
276
- setFocusedCell({ rowIndex: focusedCell.rowIndex, columnId: '' })
277
- }
278
- }, [focusedCell])
256
+ void navigate({ to: '${model.admin.page.route}', search: { selectedKey, focusedCell: undefined } })
257
+ }, [navigate, selectedKey])
279
258
 
280
259
  // Clear entity filter (go back to model overview)
281
260
  const handleClearEntity = useCallback(() => {
282
- setFocusedCell(null)
261
+ void navigate({ to: '${model.admin.page.route}', search: { selectedKey: undefined, focusedCell: undefined } })
283
262
  setSelectedRowIds([])
284
- }, [])
263
+ }, [navigate])
285
264
 
286
265
  const handleFilterChange = useCallback((key: ${model.types.filter.fieldType.name} | 'globalSearch', val: any) => {
287
266
  setFilters((prev) => {
@@ -302,6 +281,15 @@ export default function ${model.admin.page.pageComponent.name}({ selectedKey }:
302
281
  debouncedFilterChange('globalSearch', value)
303
282
  }, [debouncedFilterChange])
304
283
 
284
+ // Callback when cell focus changes in the table — also sets selectedKey from the focused row
285
+ const handleCellChange = useCallback((args: { rowIndex: number; columnId: string }) => {
286
+ const row = filteredDataList?.[args.rowIndex]
287
+ const key = row?.${model.keyField.name} != null ? String(row.${model.keyField.name}) : undefined
288
+ void navigate({ to: '${model.admin.page.route}', search: { selectedKey: key, focusedCell: args.columnId || undefined } })
289
+ // Clear checkbox selection when focusing a cell
290
+ setSelectedRowIds([])
291
+ }, [navigate, filteredDataList])
292
+
305
293
  useEffect(() => {
306
294
  const prefix = 'admin-${model._conjugated.kebabCase}-filter'
307
295
 
@@ -412,25 +400,42 @@ export default function ${model.admin.page.pageComponent.name}({ selectedKey }:
412
400
  setSearchInput,
413
401
  ])
414
402
 
415
- // Handle row click - navigate to URL with keyField value
416
- const handleRowClick = useCallback((key: string | null) => {
417
- if (key) {
418
- void navigate({ to: '${model.admin.page.route}/$key', params: { key } })
419
- } else {
420
- void navigate({ to: '${model.admin.page.route}' })
421
- }
422
- }, [navigate])
423
-
424
403
  ${model.isReadonly
425
404
  ? ''
426
- : `// Handle individual cell updates - directly call mutation for the specific cell
405
+ : `// Batch cell updates: collect updates within the same microtask and send as one updateFieldMany
406
+ const pendingUpdatesRef = useRef<Map<string, { field: string; value: unknown; ids: ${model.types.id.name}[] }> | null>(null)
407
+
427
408
  const handleCellUpdate = useCallback((args: { rowIndex: number; columnId: string; value: unknown }) => {
428
409
  const row = filteredDataList?.[args.rowIndex]
429
410
  if (!row) return
430
411
 
431
- // Call mutation directly for this specific cell change
432
- void updateFieldMutation({ id: row.id, field: args.columnId, value: args.value } as Parameters<typeof updateFieldMutation>[0])
433
- }, [filteredDataList, updateFieldMutation])
412
+ // Initialize batch map and schedule flush on first call in this microtask
413
+ if (!pendingUpdatesRef.current) {
414
+ pendingUpdatesRef.current = new Map()
415
+ queueMicrotask(() => {
416
+ const pending = pendingUpdatesRef.current
417
+ pendingUpdatesRef.current = null
418
+ if (!pending) return
419
+
420
+ for (const entry of pending.values()) {
421
+ if (entry.ids.length === 1) {
422
+ void updateFieldMutation({ id: entry.ids[0], field: entry.field, value: entry.value } as Parameters<typeof updateFieldMutation>[0])
423
+ } else {
424
+ void updateFieldManyMutation({ ids: entry.ids, field: entry.field, value: entry.value } as Parameters<typeof updateFieldManyMutation>[0])
425
+ }
426
+ }
427
+ })
428
+ }
429
+
430
+ // Group by field+value so identical field updates across rows get batched
431
+ const key = \`\${args.columnId}::\${JSON.stringify(args.value)}\`
432
+ const existing = pendingUpdatesRef.current.get(key)
433
+ if (existing) {
434
+ existing.ids.push(row.id)
435
+ } else {
436
+ pendingUpdatesRef.current.set(key, { field: args.columnId, value: args.value, ids: [row.id] })
437
+ }
438
+ }, [filteredDataList, updateFieldMutation, updateFieldManyMutation])
434
439
 
435
440
  function handleRemoveRows(rows: ${model.types.id.name}[]) {
436
441
  void deleteManyMutation(rows)
@@ -470,7 +475,6 @@ export default function ${model.admin.page.pageComponent.name}({ selectedKey }:
470
475
  onCellChange={handleCellChange}
471
476
  onRowSelectionChange={handleRowSelectionChange}
472
477
  selectedKey={selectedKey}
473
- onRowClick={handleRowClick}
474
478
  keyField="${model.keyField.name}"
475
479
  hasNextPage={hasNextPage}
476
480
  fetchNextPage={fetchNextPage}
@@ -1 +1 @@
1
- {"version":3,"file":"model-admin-page.generator.js","sourceRoot":"","sources":["../../../src/frontend-admin/generators/model-admin-page.generator.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"model-admin-page.generator.js","sourceRoot":"","sources":["../../../src/frontend-admin/generators/model-admin-page.generator.ts"],"names":[],"mappings":"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"}
@@ -78,14 +78,16 @@ function generatePage({ page, paths, vfs, content, }) {
78
78
  vfs.write((0, node_path_1.join)(paths.routes, `${page.route}.lazy.tsx`), generateOutlet(page));
79
79
  return;
80
80
  }
81
- // Model admin pages with keyField routing use outlet pattern with index and $key routes
81
+ // Model admin pages with keyField routing render the page in the layout route
82
+ // with useMatch to optionally read the $key param. This prevents re-mounting
83
+ // the page component when navigating between /admin/{model} and /admin/{model}/$key.
82
84
  if (page.hasKeyFieldRouting) {
83
- // Generate outlet route at /admin/{model}
84
- vfs.write((0, node_path_1.join)(paths.routes, `${page.route}.lazy.tsx`), generateOutlet(page));
85
- // Generate index route at /admin/{model}/ (no key selected)
86
- vfs.write((0, node_path_1.join)(paths.routes, `${page.route}/index.lazy.tsx`), generateKeyFieldIndexRoute(page));
87
- // Generate $key route at /admin/{model}/$key
88
- vfs.write((0, node_path_1.join)(paths.routes, `${page.route}/$key.lazy.tsx`), generateKeyFieldParamRoute(page));
85
+ // Generate layout route at /admin/{model} - renders page directly with useMatch
86
+ vfs.write((0, node_path_1.join)(paths.routes, `${page.route}.tsx`), generateKeyFieldLayoutRoute(page));
87
+ // Generate index route at /admin/{model}/ (renders null, layout handles rendering)
88
+ // vfs.write(join(paths.routes, `${page.route}/index.lazy.tsx`), generateKeyFieldChildRoute(page))
89
+ // Generate $key route at /admin/{model}/$key (renders null, layout handles rendering)
90
+ // vfs.write(join(paths.routes, `${page.route}/$key.lazy.tsx`), generateKeyFieldChildRoute(page, '/$key'))
89
91
  for (const alias of page.aliases ?? []) {
90
92
  vfs.write((0, node_path_1.join)(paths.routes, `${alias}.tsx`), generateAliasRoute({ alias, page }));
91
93
  }
@@ -134,38 +136,28 @@ export const Route = createFileRoute('${joinRoutes('_auth-routes', alias)}')({
134
136
  })`;
135
137
  }
136
138
  /**
137
- * Generate the index route for keyField routing (no key selected)
138
- * This renders the page component with no selectedKey
139
+ * Generate the layout route for keyField routing.
140
+ * Renders the page component directly at the layout level with useMatch
141
+ * to optionally read the $key param from the child route.
142
+ * This prevents re-mounting the page when navigating between index and $key routes.
139
143
  */
140
- function generateKeyFieldIndexRoute({ pageComponent, route }) {
144
+ function generateKeyFieldLayoutRoute({ pageComponent, route }) {
141
145
  if (!route.startsWith('/')) {
142
146
  throw new Error(`Route for page ${pageComponent.name} must start with '/': ${route}!`);
143
147
  }
144
148
  return `import ${pageComponent.name} from '${pageComponent.location}'
145
- import { createLazyFileRoute } from '@tanstack/react-router'
149
+ import { createFileRoute } from '@tanstack/react-router'
150
+ import { z } from 'zod'
146
151
 
147
- export const Route = createLazyFileRoute('${joinRoutes('_auth-routes', route)}/')({
148
- component: () => <${pageComponent.name} />,
149
- })`;
150
- }
151
- /**
152
- * Generate the $key param route for keyField routing (with key selected)
153
- * This renders the page component with selectedKey from URL params
154
- */
155
- function generateKeyFieldParamRoute({ pageComponent, route }) {
156
- if (!route.startsWith('/')) {
157
- throw new Error(`Route for page ${pageComponent.name} must start with '/': ${route}!`);
158
- }
159
- return `import ${pageComponent.name} from '${pageComponent.location}'
160
- import { createLazyFileRoute } from '@tanstack/react-router'
152
+ const zSearchParams = z.object({
153
+ selectedKey: z.string().optional(),
154
+ focusedCell: z.string().optional(),
155
+ })
161
156
 
162
- function ${pageComponent.name}WithKey() {
163
- const { key } = Route.useParams()
164
- return <${pageComponent.name} selectedKey={key} />
165
- }
166
-
167
- export const Route = createLazyFileRoute('${joinRoutes('_auth-routes', route)}/$key')({
168
- component: ${pageComponent.name}WithKey,
169
- })`;
157
+ export const Route = createFileRoute('${joinRoutes('_auth-routes', route)}')({
158
+ component: ${pageComponent.name},
159
+ validateSearch: zSearchParams,
160
+ })
161
+ `;
170
162
  }
171
163
  //# sourceMappingURL=utils.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/frontend-admin/utils.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/frontend-admin/utils.ts"],"names":[],"mappings":"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"}
@@ -42,7 +42,7 @@ const ROOT_ROUTE_FILENAME = '__root.tsx';
42
42
  // CONTEXT REGISTRATION --------------------------------------------------------
43
43
  exports.base = {
44
44
  components: ['color-mode-toggle'],
45
- hooks: ['useFontsLoaded.ts', 'use-table-view-config.tsx'],
45
+ hooks: ['useFontsLoaded.ts', 'use-table-view-config.tsx', 'use-excel-io.ts', 'use-import-review.ts'],
46
46
  contextProviders: ['auth-context-provider.tsx', 'theme-context-provider.tsx'],
47
47
  packageJson: {
48
48
  // We set name and description with the context's slug in the register function as we do not have access to the schema here yet
@@ -245,7 +245,6 @@ const configureFrontendGenerator = (into) => ({
245
245
  await context.vfs.loadFile(copyToRelativeLocation(`src/context-providers/${contextProvider}`));
246
246
  }
247
247
  context.vfs.write(Path.join(target, 'tsconfig.json'), (0, tsconfig_generator_1.generateTsConfig)(context));
248
- context.vfs.write(Path.join(target, '.env'), context.vfs.get(Path.join(target, '.env.example')) ?? '');
249
248
  return context;
250
249
  },
251
250
  });