admindb 1.2.1 → 2.0.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 (205) hide show
  1. package/README.md +262 -329
  2. package/dist/app.d.ts +25 -4
  3. package/dist/app.js +79 -15
  4. package/dist/app.js.map +1 -1
  5. package/dist/auth/config.d.ts +19 -0
  6. package/dist/auth/config.js +147 -0
  7. package/dist/auth/config.js.map +1 -0
  8. package/dist/auth/crypto.d.ts +27 -0
  9. package/dist/auth/crypto.js +133 -0
  10. package/dist/auth/crypto.js.map +1 -0
  11. package/dist/auth/index.d.ts +5 -0
  12. package/dist/auth/index.js +22 -0
  13. package/dist/auth/index.js.map +1 -0
  14. package/dist/auth/middleware.d.ts +14 -0
  15. package/dist/auth/middleware.js +100 -0
  16. package/dist/auth/middleware.js.map +1 -0
  17. package/dist/auth/routes.d.ts +7 -0
  18. package/dist/auth/routes.js +78 -0
  19. package/dist/auth/routes.js.map +1 -0
  20. package/dist/auth/types.d.ts +35 -0
  21. package/dist/auth/types.js +11 -0
  22. package/dist/auth/types.js.map +1 -0
  23. package/dist/cli/args.d.ts +45 -0
  24. package/dist/cli/args.js +328 -0
  25. package/dist/cli/args.js.map +1 -0
  26. package/dist/cli/config.d.ts +56 -0
  27. package/dist/cli/config.js +133 -0
  28. package/dist/cli/config.js.map +1 -0
  29. package/dist/cli/index.d.ts +4 -0
  30. package/dist/cli/index.js +21 -0
  31. package/dist/cli/index.js.map +1 -0
  32. package/dist/cli/runner.d.ts +1 -0
  33. package/dist/cli/runner.js +222 -0
  34. package/dist/cli/runner.js.map +1 -0
  35. package/dist/cli.js +2 -127
  36. package/dist/cli.js.map +1 -1
  37. package/dist/data/datasets.d.ts +17 -0
  38. package/dist/data/datasets.js +133 -0
  39. package/dist/data/datasets.js.map +1 -0
  40. package/dist/data/detector.d.ts +30 -0
  41. package/dist/data/detector.js +472 -0
  42. package/dist/data/detector.js.map +1 -0
  43. package/dist/data/engine.d.ts +10 -0
  44. package/dist/data/engine.js +211 -0
  45. package/dist/data/engine.js.map +1 -0
  46. package/dist/data/index.d.ts +5 -0
  47. package/dist/data/index.js +22 -0
  48. package/dist/data/index.js.map +1 -0
  49. package/dist/data/strategies.d.ts +30 -0
  50. package/dist/data/strategies.js +343 -0
  51. package/dist/data/strategies.js.map +1 -0
  52. package/dist/data/types.d.ts +73 -0
  53. package/dist/data/types.js +8 -0
  54. package/dist/data/types.js.map +1 -0
  55. package/dist/db/database.d.ts +14 -146
  56. package/dist/db/database.js +208 -461
  57. package/dist/db/database.js.map +1 -1
  58. package/dist/db/export.d.ts +2 -2
  59. package/dist/db/export.js +7 -2
  60. package/dist/db/export.js.map +1 -1
  61. package/dist/db/filters.d.ts +22 -0
  62. package/dist/db/filters.js +158 -0
  63. package/dist/db/filters.js.map +1 -0
  64. package/dist/db/index.d.ts +8 -0
  65. package/dist/db/index.js +25 -0
  66. package/dist/db/index.js.map +1 -0
  67. package/dist/db/introspection.d.ts +6 -0
  68. package/dist/db/introspection.js +172 -0
  69. package/dist/db/introspection.js.map +1 -0
  70. package/dist/db/manager.d.ts +32 -19
  71. package/dist/db/manager.js +203 -44
  72. package/dist/db/manager.js.map +1 -1
  73. package/dist/db/migrations.d.ts +5 -0
  74. package/dist/db/migrations.js +110 -0
  75. package/dist/db/migrations.js.map +1 -0
  76. package/dist/db/postgres.d.ts +85 -0
  77. package/dist/db/postgres.js +745 -0
  78. package/dist/db/postgres.js.map +1 -0
  79. package/dist/db/types.d.ts +206 -0
  80. package/dist/db/types.js +7 -0
  81. package/dist/db/types.js.map +1 -0
  82. package/dist/index.d.ts +9 -2
  83. package/dist/index.js +46 -4
  84. package/dist/index.js.map +1 -1
  85. package/dist/public/css/app.css +1 -1
  86. package/dist/public/css/input.css +74 -11
  87. package/dist/public/js/app.js +142 -0
  88. package/dist/public/js/browse.js +591 -104
  89. package/dist/public/js/databases.js +105 -13
  90. package/dist/public/js/designer.js +40 -2
  91. package/dist/public/js/forms.js +610 -28
  92. package/dist/public/js/icons.js +51 -0
  93. package/dist/public/js/inspector.js +638 -0
  94. package/dist/public/js/query.js +93 -3
  95. package/dist/public/js/schema.js +170 -52
  96. package/dist/public/js/seed.js +865 -152
  97. package/dist/routes/api/helpers.d.ts +42 -0
  98. package/dist/routes/api/helpers.js +133 -0
  99. package/dist/routes/api/helpers.js.map +1 -0
  100. package/dist/routes/api/import-export.d.ts +3 -0
  101. package/dist/routes/api/import-export.js +85 -0
  102. package/dist/routes/api/import-export.js.map +1 -0
  103. package/dist/routes/api/index.d.ts +4 -0
  104. package/dist/routes/api/index.js +37 -0
  105. package/dist/routes/api/index.js.map +1 -0
  106. package/dist/routes/api/query.d.ts +3 -0
  107. package/dist/routes/api/query.js +76 -0
  108. package/dist/routes/api/query.js.map +1 -0
  109. package/dist/routes/api/rows.d.ts +3 -0
  110. package/dist/routes/api/rows.js +373 -0
  111. package/dist/routes/api/rows.js.map +1 -0
  112. package/dist/routes/api/seed.d.ts +3 -0
  113. package/dist/routes/api/seed.js +82 -0
  114. package/dist/routes/api/seed.js.map +1 -0
  115. package/dist/routes/api/tables.d.ts +3 -0
  116. package/dist/routes/api/tables.js +160 -0
  117. package/dist/routes/api/tables.js.map +1 -0
  118. package/dist/routes/databases.d.ts +8 -11
  119. package/dist/routes/databases.js +100 -66
  120. package/dist/routes/databases.js.map +1 -1
  121. package/dist/routes/index.d.ts +3 -0
  122. package/dist/routes/index.js +20 -0
  123. package/dist/routes/index.js.map +1 -0
  124. package/dist/routes/pages.d.ts +3 -3
  125. package/dist/routes/pages.js +147 -62
  126. package/dist/routes/pages.js.map +1 -1
  127. package/dist/serverless.d.ts +40 -0
  128. package/dist/serverless.js +210 -0
  129. package/dist/serverless.js.map +1 -0
  130. package/dist/sql/generator.d.ts +4 -3
  131. package/dist/sql/generator.js +103 -6
  132. package/dist/sql/generator.js.map +1 -1
  133. package/dist/sql/index.d.ts +2 -0
  134. package/dist/sql/index.js +19 -0
  135. package/dist/sql/index.js.map +1 -0
  136. package/dist/types/api.d.ts +412 -0
  137. package/dist/types/api.js +9 -0
  138. package/dist/types/api.js.map +1 -0
  139. package/dist/utils/colors.d.ts +40 -0
  140. package/dist/utils/colors.js +64 -0
  141. package/dist/utils/colors.js.map +1 -0
  142. package/dist/{util.d.ts → utils/common.d.ts} +10 -6
  143. package/dist/{util.js → utils/common.js} +80 -13
  144. package/dist/utils/common.js.map +1 -0
  145. package/dist/utils/csv.js.map +1 -0
  146. package/dist/utils/datatype.d.ts +49 -0
  147. package/dist/utils/datatype.js +222 -0
  148. package/dist/utils/datatype.js.map +1 -0
  149. package/dist/utils/icons.d.ts +11 -0
  150. package/dist/utils/icons.js +72 -0
  151. package/dist/utils/icons.js.map +1 -0
  152. package/dist/utils/index.d.ts +4 -0
  153. package/dist/utils/index.js +21 -0
  154. package/dist/utils/index.js.map +1 -0
  155. package/dist/{logger.d.ts → utils/logger.d.ts} +1 -1
  156. package/dist/utils/logger.js +40 -0
  157. package/dist/utils/logger.js.map +1 -0
  158. package/dist/views/layouts/main.hbs +33 -11
  159. package/dist/views/pages/databases.hbs +182 -74
  160. package/dist/views/pages/designer.hbs +9 -6
  161. package/dist/views/pages/error.hbs +3 -3
  162. package/dist/views/pages/form.hbs +5 -3
  163. package/dist/views/pages/home.hbs +22 -13
  164. package/dist/views/pages/login.hbs +111 -0
  165. package/dist/views/pages/query.hbs +8 -6
  166. package/dist/views/pages/schema.hbs +41 -13
  167. package/dist/views/pages/seed.hbs +200 -54
  168. package/dist/views/pages/table.hbs +152 -72
  169. package/dist/views/partials/icon.hbs +2 -0
  170. package/dist/views/partials/navbar.hbs +69 -25
  171. package/dist/views/partials/sidebar.hbs +108 -94
  172. package/package.json +11 -4
  173. package/dist/args.d.ts +0 -28
  174. package/dist/args.js +0 -187
  175. package/dist/args.js.map +0 -1
  176. package/dist/config.d.ts +0 -17
  177. package/dist/config.js +0 -23
  178. package/dist/config.js.map +0 -1
  179. package/dist/csv.js.map +0 -1
  180. package/dist/data/generator.d.ts +0 -86
  181. package/dist/data/generator.js +0 -1031
  182. package/dist/data/generator.js.map +0 -1
  183. package/dist/logger.js +0 -25
  184. package/dist/logger.js.map +0 -1
  185. package/dist/routes/api.d.ts +0 -9
  186. package/dist/routes/api.js +0 -848
  187. package/dist/routes/api.js.map +0 -1
  188. package/dist/test/classifier.test.d.ts +0 -1
  189. package/dist/test/classifier.test.js +0 -44
  190. package/dist/test/classifier.test.js.map +0 -1
  191. package/dist/test/csv.test.d.ts +0 -1
  192. package/dist/test/csv.test.js +0 -64
  193. package/dist/test/csv.test.js.map +0 -1
  194. package/dist/test/database.test.d.ts +0 -1
  195. package/dist/test/database.test.js +0 -402
  196. package/dist/test/database.test.js.map +0 -1
  197. package/dist/test/generator.test.d.ts +0 -1
  198. package/dist/test/generator.test.js +0 -132
  199. package/dist/test/generator.test.js.map +0 -1
  200. package/dist/test/manager.test.d.ts +0 -1
  201. package/dist/test/manager.test.js +0 -146
  202. package/dist/test/manager.test.js.map +0 -1
  203. package/dist/util.js.map +0 -1
  204. /package/dist/{csv.d.ts → utils/csv.d.ts} +0 -0
  205. /package/dist/{csv.js → utils/csv.js} +0 -0
@@ -1,86 +1,232 @@
1
- <div class="space-y-5">
1
+ {{!-- Page: Mock & Seed Data Generator · URL: /tables/:table/seed --}}
2
+ <div class="space-y-6">
3
+
2
4
  <!-- Header -->
3
- <div class="flex flex-wrap items-center justify-between gap-3">
5
+ <div class="flex flex-wrap items-center justify-between gap-4 border-b border-base-200 pb-5">
4
6
  <div class="flex items-center gap-3">
5
7
  <a href="{{basePath}}/tables/{{table}}" class="btn btn-circle btn-ghost btn-sm" aria-label="Back to table">
6
- <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M10 19l-7-7m0 0l7-7m-7 7h18" /></svg>
8
+ {{{icon "arrowLeft" class="h-5 w-5"}}}
7
9
  </a>
8
10
  <div>
9
- <h1 class="font-mono text-2xl font-bold tracking-tight">{{table}}</h1>
10
- <p class="text-sm text-base-content/55">Data generator — fill the table with realistic rows in one transaction.</p>
11
+ <div class="flex flex-wrap items-center gap-2">
12
+ <h1 class="font-mono text-2xl font-bold tracking-tight">{{table}}</h1>
13
+ <span class="badge badge-sm badge-neutral font-mono">{{rowCount}} rows in DB</span>
14
+ <span class="badge badge-sm badge-ghost font-mono">{{colCount}} columns</span>
15
+ </div>
16
+ <p class="mt-0.5 text-xs text-base-content/55">Data generator — fill the table with realistic mock data, simulate sparse records, and preview in real time.</p>
11
17
  </div>
12
18
  </div>
13
- <div class="flex flex-wrap gap-2">
14
- {{#unless readonly}}
15
- <button id="seed-preview" type="button" class="btn btn-outline btn-sm gap-1.5">
16
- <svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M10 20l4-16m4 4l4 4-4 4M6 16l-4-4 4-4" /></svg>
17
- Preview SQL
19
+ <div class="flex flex-wrap items-center gap-2">
20
+ <!-- Presets dropdown -->
21
+ <div class="dropdown dropdown-end">
22
+ <button tabindex="0" type="button" class="btn btn-outline btn-sm gap-1.5">
23
+ {{{icon "seed" class="h-4 w-4"}}}
24
+ Presets
25
+ {{{icon "chevronDown" class="h-3.5 w-3.5 opacity-60"}}}
18
26
  </button>
19
- <button id="seed-insert" type="button" class="btn btn-primary btn-sm gap-1.5">
20
- <svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M12 9v3m0 0v3m0-3h3m-3 0H9m12 0a9 9 0 11-18 0 9 9 0 0118 0z" /></svg>
21
- Insert rows
27
+ <ul tabindex="0" class="dropdown-content z-20 menu p-2 shadow-lg bg-base-100 rounded-xl w-56 border border-base-200 text-xs">
28
+ <li><button type="button" id="preset-realistic" class="py-2">✨ Realistic Mock Data</button></li>
29
+ <li><button type="button" id="preset-minimal" class="py-2">⚡ Minimal (Required Only)</button></li>
30
+ <li><button type="button" id="preset-sparse" class="py-2">🎲 Sparse (30% Nullables)</button></li>
31
+ <li><button type="button" id="preset-numbered" class="py-2">🔢 Sequential & Numbered</button></li>
32
+ <li class="border-t border-base-200 my-1"></li>
33
+ <li><button type="button" id="seed-export-config" class="py-2">💾 Export Plan as JSON</button></li>
34
+ <li><button type="button" id="seed-import-config" class="py-2">📥 Import Plan JSON…</button></li>
35
+ </ul>
36
+ </div>
37
+
38
+ <button id="seed-preview" type="button" class="btn btn-outline btn-sm gap-1.5">
39
+ {{{icon "inspect" class="h-4 w-4 text-primary"}}}
40
+ Preview Data
41
+ </button>
42
+
43
+ {{#unless readonly}}
44
+ <button id="seed-insert" type="button" class="btn btn-primary btn-sm gap-1.5 shadow-sm">
45
+ {{{icon "plus" class="h-4 w-4"}}}
46
+ Insert Rows
22
47
  </button>
23
48
  {{else}}
24
- <span class="inline-flex items-center gap-1.5 text-sm font-medium text-warning">
25
- <svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M12 15v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z" /></svg>
26
- Read-only — you can preview generated SQL but not insert rows.
49
+ <span class="inline-flex items-center gap-1.5 text-xs font-medium text-warning bg-warning/10 px-2.5 py-1.5 rounded-lg">
50
+ {{{icon "lock" class="h-4 w-4"}}}
51
+ Read-only database
27
52
  </span>
28
53
  {{/unless}}
29
54
  </div>
30
55
  </div>
31
56
 
32
- <!-- Row count -->
33
- <div class="app-card p-4">
34
- <div class="flex flex-wrap items-end gap-x-5 gap-y-3">
35
- <div class="form-control w-44">
36
- <label class="field-label" for="seed-count">Rows to generate</label>
37
- <input id="seed-count" type="number" min="1" max="{{maxRows}}" value="10" class="field-input" />
57
+ <!-- Configuration Bar -->
58
+ <div class="app-card p-5 bg-base-100">
59
+ <div class="grid grid-cols-1 gap-5 lg:grid-cols-12 lg:items-end">
60
+ <!-- Row count control -->
61
+ <div class="lg:col-span-4 space-y-1.5">
62
+ <label class="field-label !mb-0 font-medium" for="seed-count">
63
+ <span>Rows to generate</span>
64
+ <span class="text-xs text-base-content/45 font-normal">(max {{maxRows}})</span>
65
+ </label>
66
+ <div class="flex items-center gap-2">
67
+ <input id="seed-count" type="number" min="1" max="{{maxRows}}" value="10" class="field-input w-28 font-mono font-medium" />
68
+ <div class="flex flex-wrap items-center gap-1">
69
+ {{#each quickCounts}}
70
+ <button type="button" class="seed-quick btn btn-outline btn-xs px-2.5" data-n="{{this}}">{{this}}</button>
71
+ {{/each}}
72
+ </div>
73
+ </div>
38
74
  </div>
39
- <div class="flex items-center gap-1.5 pb-0.5">
40
- {{#each quickCounts}}
41
- <button type="button" class="seed-quick btn btn-outline btn-xs" data-n="{{this}}">{{this}}</button>
42
- {{/each}}
75
+
76
+ <!-- Column Search Filter -->
77
+ <div class="lg:col-span-4 space-y-1.5">
78
+ <label class="field-label !mb-0 font-medium" for="seed-search">
79
+ <span>Filter columns</span>
80
+ </label>
81
+ <div class="relative">
82
+ <span class="absolute inset-y-0 left-0 flex items-center pl-3 pointer-events-none text-base-content/40">
83
+ {{{icon "search" class="h-4 w-4"}}}
84
+ </span>
85
+ <input id="seed-search" type="text" placeholder="Search column by name or type..." class="field-input pl-9 text-xs" />
86
+ </div>
87
+ </div>
88
+
89
+ <!-- Seeding options (truncate / clear) -->
90
+ <div class="lg:col-span-4 flex flex-col justify-end space-y-2">
91
+ {{#unless readonly}}
92
+ <label class="cursor-pointer flex items-center gap-2 text-xs font-medium text-base-content/80 hover:text-base-content transition-colors">
93
+ <input id="seed-truncate" type="checkbox" class="checkbox checkbox-xs checkbox-error rounded" />
94
+ <span class="flex items-center gap-1 text-error/90">
95
+ {{{icon "trash" class="h-3.5 w-3.5"}}}
96
+ Clear table before inserting (DELETE all rows)
97
+ </span>
98
+ </label>
99
+ {{/unless}}
100
+ <p class="text-[11px] text-base-content/45 leading-tight">Rows are inserted in a single atomic transaction. Any constraint failure safely rolls back.</p>
43
101
  </div>
44
- <p class="pb-0.5 text-xs text-base-content/45">Up to <b class="tabular-nums">{{maxRows}}</b> rows. The insert is transactional — a failed row rolls everything back.</p>
45
102
  </div>
46
103
  </div>
47
104
 
48
- <!-- Column strategies -->
49
- <div class="flex flex-wrap items-center justify-between gap-2">
50
- <h2 class="flex items-center gap-2 text-sm font-semibold uppercase tracking-wide text-base-content/45">
51
- <svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M19 11H5m14 0a2 2 0 012 2v6a2 2 0 01-2 2H5a2 2 0 01-2-2v-6a2 2 0 012-2m14 0V9a2 2 0 00-2-2M5 11V9a2 2 0 012-2m0 0V5a2 2 0 012-2h6a2 2 0 012 2v2M7 7h10" /></svg>
52
- Column strategies
53
- </h2>
54
- <div class="flex flex-wrap items-center gap-1.5">
55
- <button id="seed-apply-all" type="button" class="btn btn-ghost btn-xs gap-1">Apply strategy to all…</button>
56
- <button id="seed-reset" type="button" class="btn btn-ghost btn-xs gap-1">Reset defaults</button>
105
+ <!-- Column strategies section -->
106
+ <div class="space-y-3">
107
+ <div class="flex flex-wrap items-center justify-between gap-2">
108
+ <div class="flex items-center gap-2">
109
+ <h2 class="text-sm font-semibold uppercase tracking-wider text-base-content/50">Column Strategies</h2>
110
+ <span id="seed-col-count-badge" class="badge badge-sm badge-ghost font-mono"></span>
111
+ </div>
112
+ <div class="flex flex-wrap items-center gap-1.5">
113
+ <button id="seed-refresh-samples" type="button" class="btn btn-ghost btn-xs gap-1 text-base-content/60" title="Refresh live sample previews">
114
+ {{{icon "refresh" class="h-3.5 w-3.5"}}}
115
+ Refresh Samples
116
+ </button>
117
+ <button id="seed-apply-all" type="button" class="btn btn-ghost btn-xs gap-1 text-base-content/60">
118
+ {{{icon "duplicate" class="h-3.5 w-3.5"}}}
119
+ Apply strategy to all…
120
+ </button>
121
+ <button id="seed-reset" type="button" class="btn btn-ghost btn-xs gap-1 text-base-content/60">
122
+ {{{icon "refresh" class="h-3.5 w-3.5"}}}
123
+ Reset Defaults
124
+ </button>
125
+ </div>
126
+ </div>
127
+
128
+ <!-- Cards Grid -->
129
+ <div id="seed-columns" class="grid grid-cols-1 gap-3.5 md:grid-cols-2 2xl:grid-cols-3"></div>
130
+ <div id="seed-empty-search" class="hidden p-8 text-center app-card">
131
+ <p class="text-sm text-base-content/50">No columns match the current search query.</p>
57
132
  </div>
58
133
  </div>
59
- <div id="seed-columns" class="grid grid-cols-1 gap-3 md:grid-cols-2 xl:grid-cols-3"></div>
60
134
 
61
- <!-- Feedback (warnings) -->
135
+ <!-- Feedback / Warnings Alert -->
62
136
  <div id="seed-feedback" class="hidden"></div>
63
137
 
64
- <!-- Generated SQL preview -->
65
- <div id="seed-sql" class="hidden">
66
- <div class="app-card">
67
- <div class="flex items-center justify-between border-b border-base-200 px-5 py-3.5">
68
- <h2 class="flex items-center gap-2 text-sm font-semibold uppercase tracking-wide text-base-content/45">
69
- <span class="grid h-6 w-6 place-items-center rounded-md bg-primary/10 text-primary">
70
- <svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M10 20l4-16m4 4l4 4-4 4M6 16l-4-4 4-4" /></svg>
71
- </span>
72
- Generated SQL
73
- </h2>
74
- <button id="seed-copy" type="button" class="btn btn-ghost btn-xs gap-1">
75
- <svg xmlns="http://www.w3.org/2000/svg" class="h-3.5 w-3.5" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M8 7H5a2 2 0 00-2 2v9a2 2 0 002 2h9a2 2 0 002-2v-2m-4-7h3a2 2 0 012 2v9a2 2 0 01-2 2h-3" /></svg>
76
- Copy
77
- </button>
138
+ <!-- Interactive Dual-Mode Preview Section -->
139
+ <div id="seed-preview-card" class="hidden app-card overflow-hidden transition-all duration-200">
140
+ <div class="flex flex-wrap items-center justify-between border-b border-base-200 bg-base-200/40 px-5 py-3 gap-3">
141
+ <div class="flex items-center gap-3">
142
+ <div class="tabs tabs-boxed bg-base-300/40 p-0.5 rounded-lg">
143
+ <button id="tab-table-view" type="button" class="tab tab-sm tab-active font-medium gap-1.5">
144
+ {{{icon "table" class="h-3.5 w-3.5"}}}
145
+ Table Preview
146
+ </button>
147
+ <button id="tab-sql-view" type="button" class="tab tab-sm font-medium gap-1.5">
148
+ {{{icon "sql" class="h-3.5 w-3.5"}}}
149
+ SQL Statements
150
+ </button>
151
+ </div>
152
+ <span id="preview-summary-badge" class="badge badge-sm badge-ghost font-mono"></span>
78
153
  </div>
79
- <div class="p-4">
80
- <pre class="code-panel max-h-[32rem] overflow-auto"><code id="seed-sql-code"></code></pre>
154
+
155
+ <div class="flex flex-wrap items-center gap-1.5">
156
+ <button id="seed-export-csv" type="button" class="btn btn-ghost btn-xs gap-1 text-base-content/70 hover:text-primary">
157
+ {{{icon "export" class="h-3.5 w-3.5"}}}
158
+ Export CSV
159
+ </button>
160
+ <button id="seed-export-json" type="button" class="btn btn-ghost btn-xs gap-1 text-base-content/70 hover:text-primary">
161
+ {{{icon "export" class="h-3.5 w-3.5"}}}
162
+ Export JSON
163
+ </button>
164
+ <button id="seed-copy-sql" type="button" class="btn btn-ghost btn-xs gap-1 text-base-content/70 hover:text-primary">
165
+ {{{icon "copy" class="h-3.5 w-3.5"}}}
166
+ Copy SQL
167
+ </button>
168
+ <button id="seed-download-sql" type="button" class="btn btn-ghost btn-xs gap-1 text-base-content/70 hover:text-primary">
169
+ {{{icon "export" class="h-3.5 w-3.5"}}}
170
+ Download .sql
171
+ </button>
81
172
  </div>
82
173
  </div>
174
+
175
+ <!-- View 1: Interactive Table View -->
176
+ <div id="seed-table-view-container" class="overflow-x-auto max-h-[32rem]">
177
+ <table class="table table-sm table-pin-rows table-zebra w-full text-xs">
178
+ <thead id="seed-preview-thead" class="bg-base-200 font-mono text-[11px] text-base-content/70"></thead>
179
+ <tbody id="seed-preview-tbody"></tbody>
180
+ </table>
181
+ </div>
182
+
183
+ <!-- View 2: SQL View -->
184
+ <div id="seed-sql-view-container" class="hidden p-4">
185
+ <pre class="code-panel max-h-[32rem] overflow-auto"><code id="seed-sql-code"></code></pre>
186
+ </div>
83
187
  </div>
84
188
  </div>
189
+
190
+ <!-- Config JSON Modal -->
191
+ <dialog id="seed-config-dialog" class="modal">
192
+ <div class="modal-box app-card max-w-lg">
193
+ <h3 id="seed-config-dialog-title" class="text-base font-bold">Seed Plan Configuration</h3>
194
+ <p class="mt-1 text-xs text-base-content/60">Export or paste a JSON configuration for column generator settings.</p>
195
+ <textarea id="seed-config-textarea" rows="12" class="field-input mt-3 w-full font-mono text-xs" spellcheck="false"></textarea>
196
+ <div class="mt-4 flex justify-end gap-2">
197
+ <button id="seed-config-dialog-cancel" type="button" class="btn btn-ghost btn-sm">Close</button>
198
+ <button id="seed-config-dialog-apply" type="button" class="btn btn-primary btn-sm">Apply Configuration</button>
199
+ </div>
200
+ </div>
201
+ <form method="dialog" class="modal-backdrop">
202
+ <button>close</button>
203
+ </form>
204
+ </dialog>
205
+
206
+ <!-- Truncate Confirmation Modal -->
207
+ <dialog id="seed-truncate-dialog" class="modal">
208
+ <div class="modal-box app-card max-w-md border border-error/30">
209
+ <div class="flex items-center gap-3 text-error">
210
+ <span class="grid h-10 w-10 shrink-0 place-items-center rounded-xl bg-error/10">
211
+ {{{icon "warning" class="h-6 w-6"}}}
212
+ </span>
213
+ <div>
214
+ <h3 class="text-base font-bold text-base-content">Clear table before inserting?</h3>
215
+ <p class="text-xs text-error font-medium">All existing rows in "{{table}}" will be permanently deleted.</p>
216
+ </div>
217
+ </div>
218
+ <p class="mt-3 text-xs text-base-content/60 leading-relaxed">
219
+ This will execute <code>DELETE FROM "{{table}}"</code> before inserting the newly generated seed rows. This action cannot be undone.
220
+ </p>
221
+ <div class="mt-5 flex justify-end gap-2">
222
+ <button id="seed-truncate-cancel" type="button" class="btn btn-ghost btn-sm">Cancel</button>
223
+ <button id="seed-truncate-confirm" type="button" class="btn btn-error btn-sm">Yes, Clear & Insert</button>
224
+ </div>
225
+ </div>
226
+ <form method="dialog" class="modal-backdrop">
227
+ <button>close</button>
228
+ </form>
229
+ </dialog>
230
+
85
231
  <script id="seed-config" type="application/json">{{{json seedConfig}}}</script>
86
232
  <script src="{{basePath}}/js/seed.js" defer></script>