admindb 2.5.0 → 2.6.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +20 -20
- package/dist/app.js +13 -1
- package/dist/core/diff/data-differ.d.ts +1 -0
- package/dist/core/diff/data-differ.js +243 -0
- package/dist/core/diff/patch-generator.d.ts +1 -0
- package/dist/core/diff/patch-generator.js +77 -0
- package/dist/core/diff/schema-differ.d.ts +1 -0
- package/dist/core/diff/schema-differ.js +229 -0
- package/dist/core/router.d.ts +1 -1
- package/dist/core/transfer/dialect-mapper.d.ts +1 -0
- package/dist/core/transfer/dialect-mapper.js +303 -0
- package/dist/core/transfer/masking.d.ts +1 -0
- package/dist/core/transfer/masking.js +49 -0
- package/dist/core/transfer/sync-engine.d.ts +1 -0
- package/dist/core/transfer/sync-engine.js +234 -0
- package/dist/core/transfer/topological-sort.d.ts +1 -0
- package/dist/core/transfer/topological-sort.js +55 -0
- package/dist/db/dialects/postgres/introspector.js +71 -71
- package/dist/db/dialects/sqlite/introspector.js +6 -3
- package/dist/modules/index.d.ts +1 -1
- package/dist/modules/index.js +9 -1
- package/dist/modules/search/index.d.ts +1 -0
- package/dist/modules/search/index.js +19 -0
- package/dist/modules/search/search.routes.d.ts +1 -0
- package/dist/modules/search/search.routes.js +38 -0
- package/dist/modules/search/search.service.d.ts +1 -0
- package/dist/modules/search/search.service.js +458 -0
- package/dist/modules/search/search.types.d.ts +1 -0
- package/dist/modules/search/search.types.js +2 -0
- package/dist/modules/sync/index.d.ts +1 -0
- package/dist/modules/sync/index.js +18 -0
- package/dist/modules/sync/sync.routes.d.ts +1 -0
- package/dist/modules/sync/sync.routes.js +135 -0
- package/dist/modules/sync/sync.service.d.ts +1 -0
- package/dist/modules/sync/sync.service.js +41 -0
- package/dist/public/css/app.css +2 -1
- package/dist/public/js/browse.js +1 -1
- package/dist/public/js/search.js +1 -0
- package/dist/public/js/sync.js +1 -0
- package/dist/utils/icons.js +3 -0
- package/dist/views/layouts/main.hbs +1 -1
- package/dist/views/pages/error.hbs +1 -10
- package/dist/views/pages/seed-select.hbs +252 -1
- package/dist/views/pages/seed.hbs +307 -1
- package/dist/views/pages/sync.hbs +1 -0
- package/dist/views/pages/table.hbs +1 -1
- package/dist/views/partials/navbar.hbs +1 -1
- package/dist/views/partials/sidebar.hbs +1 -1
- package/docs/EXAMPLES.md +579 -579
- package/docs/SECURITY.md +265 -265
- package/package.json +14 -9
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<div class="space-y-6 max-w-7xl mx-auto">
|
|
2
|
<div class="relative overflow-hidden rounded-2xl border border-primary/20 bg-gradient-to-br from-base-100 via-base-200/50 to-primary/5 p-6 shadow-sm">
|
|
1
3
|
<div class="relative z-10 flex flex-col md:flex-row md:items-center md:justify-between gap-4">
|
|
2
4
|
<div>
|
|
3
5
|
<div class="flex items-center gap-2 mb-1">
|
|
4
6
|
<span class="badge badge-primary badge-sm font-mono uppercase tracking-wider font-bold">Studio</span>
|
|
5
7
|
<span class="text-xs text-base-content/50 font-mono">SQLite ⇄ PostgreSQL</span>
|
|
6
8
|
</div>
|
|
7
9
|
<h1 class="text-2xl font-bold tracking-tight flex items-center gap-2.5">
|
|
8
10
|
<span class="p-2 rounded-xl bg-primary/10 text-primary border border-primary/20 shadow-inner">
|
|
9
11
|
{{{icon "diff" class="h-6 w-6"}}}
|
|
10
12
|
</span>
|
|
11
13
|
Diff & Replication Studio
|
|
12
14
|
</h1>
|
|
13
15
|
<p class="mt-1.5 text-xs text-base-content/70 max-w-2xl leading-relaxed">
|
|
14
16
|
Compare database schemas with Git-style unified diffs, inspect table data row-by-row, generate UP/DOWN SQL migration patches, and safely clone databases across engines and environments.
|
|
15
17
|
</p>
|
|
16
18
|
</div>
|
|
17
19
|
<div class="flex flex-wrap items-center gap-2 pt-2 md:pt-0">
|
|
18
20
|
<button id="btn-generate-sql" type="button" class="btn btn-outline btn-sm gap-1.5 shadow-sm transition hover:scale-[1.02]" disabled title="Generate UP and DOWN SQL migration scripts">
|
|
19
21
|
{{{icon "sql" class="h-4 w-4 text-primary"}}}
|
|
20
22
|
Migration SQL
|
|
21
23
|
</button>
|
|
22
24
|
<button id="btn-dry-run" type="button" class="btn btn-outline btn-info btn-sm gap-1.5 shadow-sm transition hover:scale-[1.02]" disabled title="Simulate replication without writing data">
|
|
23
25
|
{{{icon "inspect" class="h-4 w-4"}}}
|
|
24
26
|
Dry Run
|
|
25
27
|
</button>
|
|
26
28
|
<button id="btn-execute-sync" type="button" class="btn btn-primary btn-sm gap-1.5 shadow-sm transition hover:scale-[1.02]" disabled title="Synchronize / replicate data">
|
|
27
29
|
{{{icon "sync" class="h-4 w-4"}}}
|
|
28
30
|
Replicate Database
|
|
29
31
|
</button>
|
|
30
32
|
</div>
|
|
31
33
|
</div>
|
|
32
34
|
</div>
|
|
33
35
|
<div class="app-card border border-base-300 p-5 shadow-sm space-y-4">
|
|
34
36
|
<div class="grid grid-cols-1 items-center gap-4 lg:grid-cols-[1fr,auto,1fr]">
|
|
35
37
|
<div class="rounded-xl border border-emerald-500/30 bg-emerald-500/[0.03] p-4 space-y-3 transition hover:border-emerald-500/50">
|
|
36
38
|
<div class="flex items-center justify-between">
|
|
37
39
|
<span class="text-xs font-bold uppercase tracking-wider text-emerald-600 dark:text-emerald-400 flex items-center gap-1.5">
|
|
38
40
|
<span class="relative flex h-2 w-2">
|
|
39
41
|
<span class="animate-ping absolute inline-flex h-full w-full rounded-full bg-emerald-400 opacity-75"></span>
|
|
40
42
|
<span class="relative inline-flex rounded-full h-2 w-2 bg-emerald-500"></span>
|
|
41
43
|
</span>
|
|
42
44
|
Source Database (Origin)
|
|
43
45
|
</span>
|
|
44
46
|
<span id="src-badge-engine" class="badge badge-sm font-mono badge-success">SQLite</span>
|
|
45
47
|
</div>
|
|
46
48
|
<div>
|
|
47
49
|
<label class="text-[11px] font-semibold text-base-content/60 mb-1 block">Choose source instance:</label>
|
|
48
50
|
<select id="select-source-db" class="select select-bordered select-sm w-full font-mono text-xs focus:border-emerald-500">
|
|
49
51
|
<option value="" disabled selected>Select source database…</option>
|
|
50
52
|
{{#each databases}}
|
|
51
53
|
<option value="{{this.id}}" data-dialect="{{this.dialect}}" data-readonly="{{this.readonly}}" {{#if (eq this.id ../dbId)}}selected{{/if}}>
|
|
52
54
|
{{this.name}} ({{this.dialect}}{{#if this.readonly}} · Read-only{{/if}})
|
|
53
55
|
</option>
|
|
54
56
|
{{/each}}
|
|
55
57
|
</select>
|
|
56
58
|
</div>
|
|
57
59
|
<div class="flex items-center justify-between text-[11px] text-base-content/50 font-mono truncate" id="src-path-label">
|
|
58
60
|
<span>Select database above</span>
|
|
59
61
|
</div>
|
|
60
62
|
</div>
|
|
61
63
|
<div class="flex flex-col items-center justify-center gap-1">
|
|
62
64
|
<button id="btn-swap-dbs" type="button" class="btn btn-circle btn-sm btn-ghost border border-base-300 shadow-sm hover:bg-primary/10 hover:text-primary hover:border-primary/40 hover:rotate-180 transition-all duration-300" title="Swap direction (Source ⇄ Target)">
|
|
63
65
|
{{{icon "swap" class="h-4 w-4"}}}
|
|
64
66
|
</button>
|
|
65
67
|
<span class="text-[10px] uppercase font-mono tracking-widest text-base-content/40 font-semibold">Transfer</span>
|
|
66
68
|
</div>
|
|
67
69
|
<div class="rounded-xl border border-info/30 bg-info/[0.03] p-4 space-y-3 transition hover:border-info/50">
|
|
68
70
|
<div class="flex items-center justify-between">
|
|
69
71
|
<span class="text-xs font-bold uppercase tracking-wider text-info flex items-center gap-1.5">
|
|
70
72
|
<span class="relative flex h-2 w-2">
|
|
71
73
|
<span class="relative inline-flex rounded-full h-2 w-2 bg-info"></span>
|
|
72
74
|
</span>
|
|
73
75
|
Target Database (Destination)
|
|
74
76
|
</span>
|
|
75
77
|
<span id="tgt-badge-engine" class="badge badge-sm font-mono badge-info">PostgreSQL</span>
|
|
76
78
|
</div>
|
|
77
79
|
<div>
|
|
78
80
|
<label class="text-[11px] font-semibold text-base-content/60 mb-1 block">Choose target destination:</label>
|
|
79
81
|
<select id="select-target-db" class="select select-bordered select-sm w-full font-mono text-xs focus:border-info">
|
|
80
82
|
<option value="" disabled selected>Select target database…</option>
|
|
81
83
|
{{#each databases}}
|
|
82
84
|
<option value="{{this.id}}" data-dialect="{{this.dialect}}" data-readonly="{{this.readonly}}">
|
|
83
85
|
{{this.name}} ({{this.dialect}}{{#if this.readonly}} · Read-only{{/if}})
|
|
84
86
|
</option>
|
|
85
87
|
{{/each}}
|
|
86
88
|
</select>
|
|
87
89
|
</div>
|
|
88
90
|
<div class="flex items-center justify-between text-[11px] text-base-content/50 font-mono truncate" id="tgt-path-label">
|
|
89
91
|
<span>Select target database above</span>
|
|
90
92
|
</div>
|
|
91
93
|
</div>
|
|
92
94
|
</div>
|
|
93
95
|
<div class="pt-3 border-t border-base-200 flex flex-wrap items-center justify-between gap-3">
|
|
94
96
|
<div class="flex items-center gap-2 text-xs text-base-content/60">
|
|
95
97
|
<span class="badge badge-xs badge-info"></span>
|
|
96
98
|
<span>Select source and target instances to run schema diffing or cross-database replication.</span>
|
|
97
99
|
</div>
|
|
98
100
|
<button id="btn-compare-now" type="button" class="btn btn-primary btn-sm gap-1.5 shadow-sm transition hover:scale-[1.02]">
|
|
99
101
|
{{{icon "search" class="h-4 w-4"}}}
|
|
100
102
|
Compare Diff Now
|
|
101
103
|
</button>
|
|
102
104
|
</div>
|
|
103
105
|
</div>
|
|
104
106
|
<div class="app-card border border-base-300 overflow-hidden shadow-sm">
|
|
105
107
|
<div class="p-4 bg-base-200/40 border-b border-base-200 flex items-center justify-between cursor-pointer select-none transition hover:bg-base-200/60" id="toggle-options-header">
|
|
106
108
|
<div class="flex items-center gap-2.5">
|
|
107
109
|
<span class="p-1 rounded bg-base-300/60 text-base-content/70">
|
|
108
110
|
{{{icon "settings" class="h-4 w-4"}}}
|
|
109
111
|
</span>
|
|
110
112
|
<span class="text-sm font-bold tracking-tight">Replication & Safety Options</span>
|
|
111
113
|
<span class="badge badge-sm badge-outline font-mono text-[10px]" id="badge-active-mode">Full Clone</span>
|
|
112
114
|
</div>
|
|
113
115
|
<div class="flex items-center gap-2 text-xs text-base-content/50 font-mono">
|
|
114
116
|
<span id="options-toggle-hint">Customize mode, masking & tables</span>
|
|
115
117
|
{{{icon "chevronDown" class="h-3.5 w-3.5 transition-transform duration-200" id="options-chevron"}}}
|
|
116
118
|
</div>
|
|
117
119
|
</div>
|
|
118
120
|
<div class="p-5 space-y-5 hidden" id="options-panel">
|
|
119
121
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
|
|
120
122
|
<div class="space-y-2.5">
|
|
121
123
|
<label class="field-label font-bold text-xs uppercase tracking-wider text-base-content/70">Select Replication Strategy</label>
|
|
122
124
|
<div class="space-y-2.5">
|
|
123
125
|
<label class="flex items-start gap-3 p-3 rounded-xl border border-base-300 bg-base-100 hover:border-primary/40 hover:bg-primary/[0.02] cursor-pointer transition">
|
|
124
126
|
<input type="radio" name="sync-mode" value="full" class="radio radio-primary radio-sm mt-0.5" checked />
|
|
125
127
|
<div>
|
|
126
128
|
<div class="text-xs font-bold text-base-content flex items-center gap-2">
|
|
127
129
|
Full Clone
|
|
128
130
|
<span class="badge badge-xs badge-error">Drops & Recreates</span>
|
|
129
131
|
</div>
|
|
130
132
|
<div class="text-[11px] text-base-content/60 mt-0.5 leading-relaxed">
|
|
131
133
|
Drops target tables in dependency order, recreates DDL matching source schema, and transfers all records with automatic sequence sync.
|
|
132
134
|
</div>
|
|
133
135
|
</div>
|
|
134
136
|
</label>
|
|
135
137
|
<label class="flex items-start gap-3 p-3 rounded-xl border border-base-300 bg-base-100 hover:border-primary/40 hover:bg-primary/[0.02] cursor-pointer transition">
|
|
136
138
|
<input type="radio" name="sync-mode" value="schema_only" class="radio radio-primary radio-sm mt-0.5" />
|
|
137
139
|
<div>
|
|
138
140
|
<div class="text-xs font-bold text-base-content flex items-center gap-2">
|
|
139
141
|
Schema Only
|
|
140
142
|
<span class="badge badge-xs badge-success">Non-Destructive</span>
|
|
141
143
|
</div>
|
|
142
144
|
<div class="text-[11px] text-base-content/60 mt-0.5 leading-relaxed">
|
|
143
145
|
Creates missing tables, columns, indexes, and constraints without touching or transferring row records.
|
|
144
146
|
</div>
|
|
145
147
|
</div>
|
|
146
148
|
</label>
|
|
147
149
|
<label class="flex items-start gap-3 p-3 rounded-xl border border-base-300 bg-base-100 hover:border-primary/40 hover:bg-primary/[0.02] cursor-pointer transition">
|
|
148
150
|
<input type="radio" name="sync-mode" value="data_only_replace" class="radio radio-primary radio-sm mt-0.5" />
|
|
149
151
|
<div>
|
|
150
152
|
<div class="text-xs font-bold text-base-content flex items-center gap-2">
|
|
151
153
|
Data Only (Clean & Replace)
|
|
152
154
|
<span class="badge badge-xs badge-warning">Truncates Data</span>
|
|
153
155
|
</div>
|
|
154
156
|
<div class="text-[11px] text-base-content/60 mt-0.5 leading-relaxed">
|
|
155
157
|
Preserves existing target table schemas, truncates target data rows, and streams fresh records from source.
|
|
156
158
|
</div>
|
|
157
159
|
</div>
|
|
158
160
|
</label>
|
|
159
161
|
</div>
|
|
160
162
|
</div>
|
|
161
163
|
<div class="space-y-4">
|
|
162
164
|
<div>
|
|
163
165
|
<label class="field-label font-bold text-xs uppercase tracking-wider text-base-content/70">Anonymization & Privacy Guard</label>
|
|
164
166
|
<div class="p-3.5 rounded-xl border border-warning/30 bg-warning/[0.03] space-y-2">
|
|
165
167
|
<label class="flex items-start gap-3 cursor-pointer">
|
|
166
168
|
<input type="checkbox" id="chk-mask-data" class="checkbox checkbox-warning checkbox-sm mt-0.5" checked />
|
|
167
169
|
<div>
|
|
168
170
|
<div class="text-xs font-bold text-warning flex items-center gap-1.5">
|
|
169
171
|
{{{icon "lock" class="h-3.5 w-3.5"}}}
|
|
170
172
|
Anonymize Sensitive Data (Prod ➔ Test Masking)
|
|
171
173
|
</div>
|
|
172
174
|
<div class="text-[11px] text-base-content/65 mt-0.5 leading-relaxed">
|
|
173
175
|
Automatically replaces emails (<code class="font-mono text-[10px]">user1@masked.test</code>), password hashes, phone numbers, and full names with synthetic mock data during replication.
|
|
174
176
|
</div>
|
|
175
177
|
</div>
|
|
176
178
|
</label>
|
|
177
179
|
</div>
|
|
178
180
|
</div>
|
|
179
181
|
<div>
|
|
180
182
|
<div class="flex items-center justify-between mb-1.5">
|
|
181
183
|
<label class="field-label font-bold text-xs uppercase tracking-wider text-base-content/70 mb-0">Tables to Transfer</label>
|
|
182
184
|
<div class="flex items-center gap-2 text-xs">
|
|
183
185
|
<button type="button" id="btn-select-all-tables" class="text-primary font-semibold hover:underline">Select All</button>
|
|
184
186
|
<span class="text-base-content/30">|</span>
|
|
185
187
|
<button type="button" id="btn-deselect-all-tables" class="text-base-content/60 hover:underline">Clear</button>
|
|
186
188
|
</div>
|
|
187
189
|
</div>
|
|
188
190
|
<div id="table-checkboxes-container" class="max-h-40 overflow-y-auto p-2.5 rounded-xl border border-base-300 bg-base-100 divide-y divide-base-200/50 text-xs font-mono">
|
|
189
191
|
<span class="text-base-content/40 italic p-1 block">Select source database above to load tables.</span>
|
|
190
192
|
</div>
|
|
191
193
|
</div>
|
|
192
194
|
</div>
|
|
193
195
|
</div>
|
|
194
196
|
</div>
|
|
195
197
|
</div>
|
|
196
198
|
<div class="app-card border border-base-300 overflow-hidden shadow-sm">
|
|
197
199
|
<div class="border-b border-base-300 bg-base-200/50 px-4 pt-3 flex flex-wrap items-center justify-between gap-3">
|
|
198
200
|
<div class="tabs tabs-boxed bg-base-300/40 p-1 gap-1 rounded-xl" id="diff-tabs">
|
|
199
201
|
<button type="button" class="tab tab-sm tab-active font-semibold gap-1.5 rounded-lg" data-tab="unified">
|
|
200
202
|
{{{icon "diff" class="h-3.5 w-3.5"}}}
|
|
201
203
|
Git Unified Diff
|
|
202
204
|
</button>
|
|
203
205
|
<button type="button" class="tab tab-sm font-semibold gap-1.5 rounded-lg" data-tab="visual">
|
|
204
206
|
{{{icon "table" class="h-3.5 w-3.5"}}}
|
|
205
207
|
Visual Breakdown
|
|
206
208
|
</button>
|
|
207
209
|
<button type="button" class="tab tab-sm font-semibold gap-1.5 rounded-lg" data-tab="data">
|
|
208
210
|
{{{icon "inspect" class="h-3.5 w-3.5"}}}
|
|
209
211
|
Data Diff (Row-by-Row)
|
|
210
212
|
</button>
|
|
211
213
|
</div>
|
|
212
214
|
<div class="flex items-center gap-2 pb-2 text-xs" id="diff-stats-chips">
|
|
213
215
|
</div>
|
|
214
216
|
</div>
|
|
215
217
|
<div id="tab-content-unified" class="p-5 space-y-3">
|
|
216
218
|
<div class="flex items-center justify-between text-xs text-base-content/60">
|
|
217
219
|
<span class="font-mono text-[11px] flex items-center gap-1.5">
|
|
218
220
|
<span class="h-2 w-2 rounded-full bg-primary"></span>
|
|
219
221
|
Standard Git Patch format · Green (+) additions, Red (-) deletions, Amber (~) modifications
|
|
220
222
|
</span>
|
|
221
223
|
<button id="btn-copy-unified-diff" type="button" class="btn btn-ghost btn-xs gap-1 font-mono hover:text-primary">
|
|
222
224
|
{{{icon "copy" class="h-3 w-3"}}}
|
|
223
225
|
Copy Diff Text
|
|
224
226
|
</button>
|
|
225
227
|
</div>
|
|
226
228
|
<div id="unified-diff-view" class="bg-neutral text-neutral-content rounded-xl p-4 font-mono text-xs overflow-x-auto min-h-[300px] max-h-[600px] leading-relaxed select-text border border-neutral-focus shadow-inner">
|
|
227
229
|
<div class="text-neutral-content/40 italic text-center py-20">
|
|
228
230
|
Select source and target instances above and click <strong>Compare Diff Now</strong> to compute git-style schema differences.
|
|
229
231
|
</div>
|
|
230
232
|
</div>
|
|
231
233
|
</div>
|
|
232
234
|
<div id="tab-content-visual" class="p-5 hidden space-y-4">
|
|
233
235
|
<div class="flex flex-wrap items-center justify-between gap-3 p-2 rounded-xl bg-base-200/50 border border-base-300">
|
|
234
236
|
<div class="relative flex-1 min-w-[200px]">
|
|
235
237
|
<span class="absolute left-3 top-1/2 -translate-y-1/2 text-base-content/40 pointer-events-none">
|
|
236
238
|
{{{icon "search" class="h-3.5 w-3.5"}}}
|
|
237
239
|
</span>
|
|
238
240
|
<input type="text" id="input-filter-visual-tables" class="input input-sm input-bordered w-full pl-8 font-mono text-xs" placeholder="Filter tables by name…" autocomplete="off" />
|
|
239
241
|
</div>
|
|
240
242
|
<div class="flex items-center gap-1 text-xs" id="filter-status-buttons">
|
|
241
243
|
<button type="button" class="btn btn-xs btn-ghost btn-active js-filter-status" data-filter="all">All</button>
|
|
242
244
|
<button type="button" class="btn btn-xs btn-ghost js-filter-status text-warning" data-filter="modified">Modified</button>
|
|
243
245
|
<button type="button" class="btn btn-xs btn-ghost js-filter-status text-success" data-filter="added">Added</button>
|
|
244
246
|
<button type="button" class="btn btn-xs btn-ghost js-filter-status text-error" data-filter="removed">Removed</button>
|
|
245
247
|
</div>
|
|
246
248
|
</div>
|
|
247
249
|
<div id="visual-diff-cards" class="space-y-3">
|
|
248
250
|
<div class="text-base-content/40 italic text-center py-20">
|
|
249
251
|
No comparison performed yet. Select databases and click "Compare Diff Now".
|
|
250
252
|
</div>
|
|
251
253
|
</div>
|
|
252
254
|
</div>
|
|
253
255
|
<div id="tab-content-data" class="p-5 hidden space-y-4">
|
|
254
256
|
<div class="flex flex-wrap items-center justify-between gap-3 p-3 rounded-xl bg-base-200/50 border border-base-300">
|
|
255
257
|
<div class="flex flex-wrap items-center gap-2.5">
|
|
256
258
|
<label class="text-xs font-bold uppercase tracking-wider text-base-content/60">Table to Compare:</label>
|
|
257
259
|
<select id="select-data-diff-table" class="select select-bordered select-xs font-mono min-w-[180px]">
|
|
258
260
|
<option value="" disabled selected>Select table…</option>
|
|
259
261
|
</select>
|
|
260
262
|
<label class="text-xs font-bold uppercase tracking-wider text-base-content/60 ml-2">Sample Limit:</label>
|
|
261
263
|
<select id="select-data-diff-limit" class="select select-bordered select-xs font-mono">
|
|
262
264
|
<option value="50">50 rows</option>
|
|
263
265
|
<option value="150" selected>150 rows</option>
|
|
264
266
|
<option value="300">300 rows</option>
|
|
265
267
|
<option value="500">500 rows</option>
|
|
266
268
|
</select>
|
|
267
269
|
<button id="btn-fetch-data-diff" type="button" class="btn btn-primary btn-xs gap-1 shadow-sm">
|
|
268
270
|
{{{icon "refresh" class="h-3 w-3"}}}
|
|
269
271
|
Compare Rows
|
|
270
272
|
</button>
|
|
271
273
|
</div>
|
|
272
274
|
<div id="data-diff-stats" class="flex items-center gap-1.5 text-xs font-mono"></div>
|
|
273
275
|
</div>
|
|
274
276
|
<div id="data-diff-results" class="bg-base-200/30 rounded-xl p-4 font-mono text-xs overflow-x-auto min-h-[250px] max-h-[550px] border border-base-300">
|
|
275
277
|
<div class="text-base-content/40 italic text-center py-16">
|
|
276
278
|
Select a table and click <strong>Compare Rows</strong> to inspect added, removed, and modified data rows.
|
|
277
279
|
</div>
|
|
278
280
|
</div>
|
|
279
281
|
</div>
|
|
280
282
|
</div>
|
|
281
283
|
<div class="modal-box max-w-3xl border border-base-300 bg-base-100 p-6 space-y-4 shadow-2xl">
|
|
282
284
|
<div class="flex items-center justify-between border-b border-base-200 pb-3">
|
|
283
285
|
<h3 class="font-bold text-base flex items-center gap-2">
|
|
284
286
|
<span class="p-1 rounded bg-primary/10 text-primary">
|
|
285
287
|
{{{icon "sql" class="h-5 w-5"}}}
|
|
286
288
|
</span>
|
|
287
289
|
Generated Migration SQL Patch
|
|
288
290
|
</h3>
|
|
289
291
|
<form method="dialog">
|
|
290
292
|
<button class="btn btn-sm btn-circle btn-ghost">✕</button>
|
|
291
293
|
</form>
|
|
292
294
|
</div>
|
|
293
295
|
<div class="tabs tabs-boxed bg-base-200/60 p-1 gap-1 rounded-xl">
|
|
294
296
|
<button type="button" id="tab-up-sql" class="tab tab-sm tab-active font-bold rounded-lg">UP Script (Migrate Target)</button>
|
|
295
297
|
<button type="button" id="tab-down-sql" class="tab tab-sm font-bold rounded-lg">DOWN Script (Rollback Changes)</button>
|
|
296
298
|
</div>
|
|
297
299
|
<div class="relative">
|
|
298
300
|
<pre id="patch-sql-code" class="bg-neutral text-neutral-content p-4 rounded-xl font-mono text-xs max-h-96 overflow-auto border border-neutral-focus select-all shadow-inner leading-relaxed"></pre>
|
|
299
301
|
<div class="absolute top-3 right-3 flex items-center gap-1.5">
|
|
300
302
|
<button id="btn-copy-patch-sql" type="button" class="btn btn-xs btn-outline gap-1 bg-base-100 shadow-sm text-base-content hover:bg-base-200">
|
|
301
303
|
{{{icon "copy" class="h-3 w-3"}}}
|
|
302
304
|
Copy SQL
|
|
303
305
|
</button>
|
|
304
306
|
</div>
|
|
305
307
|
</div>
|
|
306
308
|
<div class="modal-action flex justify-between items-center pt-2 border-t border-base-200">
|
|
307
309
|
<span class="text-xs text-base-content/50">Run this script in your target database query editor to align schema structure.</span>
|
|
308
310
|
<form method="dialog">
|
|
309
311
|
<button class="btn btn-sm">Close</button>
|
|
310
312
|
</form>
|
|
311
313
|
</div>
|
|
312
314
|
</div>
|
|
313
315
|
<form method="dialog" class="modal-backdrop">
|
|
314
316
|
<button>close</button>
|
|
315
317
|
</form>
|
|
316
318
|
<div class="modal-box max-w-lg border border-base-300 bg-base-100 p-6 space-y-4 shadow-2xl">
|
|
317
319
|
<div class="flex items-center justify-between border-b border-base-200 pb-3">
|
|
318
320
|
<h3 class="font-bold text-base flex items-center gap-2" id="exec-modal-title">
|
|
319
321
|
<span class="p-1 rounded bg-error/10 text-error" id="exec-modal-icon-badge">
|
|
320
322
|
{{{icon "warning" class="h-5 w-5"}}}
|
|
321
323
|
</span>
|
|
322
324
|
Confirm Replication Execution
|
|
323
325
|
</h3>
|
|
324
326
|
<form method="dialog">
|
|
325
327
|
<button id="btn-exec-close-x" class="btn btn-sm btn-circle btn-ghost">✕</button>
|
|
326
328
|
</form>
|
|
327
329
|
</div>
|
|
328
330
|
<div id="exec-prompt-content" class="space-y-4 text-xs leading-relaxed">
|
|
329
331
|
<div id="exec-destructive-banner" class="p-4 rounded-xl border border-error/40 bg-error/[0.06] text-error space-y-2.5">
|
|
330
332
|
<div class="font-bold flex items-center gap-2 text-sm">
|
|
331
333
|
{{{icon "warning" class="h-4 w-4 shrink-0 text-error"}}}
|
|
332
334
|
Caution: Destructive Action Ahead!
|
|
333
335
|
</div>
|
|
334
336
|
<p class="text-[11.5px] leading-relaxed text-base-content/80">
|
|
335
337
|
This operation will <strong class="text-error font-bold" id="lbl-destructive-action-desc">permanently drop/truncate</strong> existing tables and data on target database <code class="font-mono font-bold text-error px-1 py-0.5 rounded bg-error/10" id="lbl-confirm-tgt-highlight"></code>.
|
|
336
338
|
</p>
|
|
337
339
|
<div class="text-[11px] text-base-content/60 font-mono">
|
|
338
340
|
Affected tables: <span id="lbl-affected-tables-list" class="font-bold text-base-content">All selected tables</span>
|
|
339
341
|
</div>
|
|
340
342
|
</div>
|
|
341
343
|
<div class="p-3.5 rounded-xl border border-base-200 bg-base-200/40 space-y-1.5 font-mono text-[11.5px]">
|
|
342
344
|
<div class="flex justify-between">
|
|
343
345
|
<span class="text-base-content/60">Source (Origin):</span>
|
|
344
346
|
<span id="lbl-confirm-src" class="font-bold text-emerald-600 dark:text-emerald-400"></span>
|
|
345
347
|
</div>
|
|
346
348
|
<div class="flex justify-between">
|
|
347
349
|
<span class="text-base-content/60">Target (Destination):</span>
|
|
348
350
|
<span id="lbl-confirm-tgt" class="font-bold text-info"></span>
|
|
349
351
|
</div>
|
|
350
352
|
<div class="flex justify-between">
|
|
351
353
|
<span class="text-base-content/60">Selected Mode:</span>
|
|
352
354
|
<span id="lbl-confirm-mode" class="font-bold"></span>
|
|
353
355
|
</div>
|
|
354
356
|
<div class="flex justify-between">
|
|
355
357
|
<span class="text-base-content/60">PII Data Anonymization:</span>
|
|
356
358
|
<span id="lbl-confirm-mask" class="font-bold text-warning"></span>
|
|
357
359
|
</div>
|
|
358
360
|
<div class="flex justify-between">
|
|
359
361
|
<span class="text-base-content/60">Tables Selected:</span>
|
|
360
362
|
<span id="lbl-confirm-tables" class="font-bold"></span>
|
|
361
363
|
</div>
|
|
362
364
|
</div>
|
|
363
365
|
<div id="exec-safety-locks" class="space-y-3 pt-1">
|
|
364
366
|
<label class="flex items-start gap-2.5 p-2.5 rounded-lg border border-base-300 bg-base-100 hover:bg-base-200/50 cursor-pointer">
|
|
365
367
|
<input type="checkbox" id="chk-confirm-destruction" class="checkbox checkbox-error checkbox-sm mt-0.5" />
|
|
366
368
|
<span class="text-[11.5px] font-medium text-base-content/80 select-none">
|
|
367
369
|
I understand that existing tables and records on the target database will be overwritten.
|
|
368
370
|
</span>
|
|
369
371
|
</label>
|
|
370
372
|
<div id="box-confirm-phrase" class="space-y-1.5">
|
|
371
373
|
<label class="text-[11px] font-bold text-base-content/70 block">
|
|
372
374
|
Type <code class="font-mono text-error font-bold px-1 rounded bg-error/10" id="lbl-required-confirm-word">OVERWRITE</code> to unlock replication:
|
|
373
375
|
</label>
|
|
374
376
|
<input type="text" id="input-confirm-phrase" class="input input-sm input-bordered w-full font-mono text-xs bg-base-100 focus:border-error" placeholder="Type here to confirm" autocomplete="off" spellcheck="false" />
|
|
375
377
|
</div>
|
|
376
378
|
</div>
|
|
377
379
|
</div>
|
|
378
380
|
<div id="exec-progress-container" class="space-y-3 hidden">
|
|
379
381
|
<div class="flex items-center justify-between text-xs font-mono">
|
|
380
382
|
<span id="exec-current-table" class="font-semibold flex items-center gap-2">
|
|
381
383
|
<span class="loading loading-spinner loading-xs text-primary"></span>
|
|
382
384
|
Synchronizing records...
|
|
383
385
|
</span>
|
|
384
386
|
<span id="exec-progress-percent" class="text-primary font-bold">0%</span>
|
|
385
387
|
</div>
|
|
386
388
|
<progress id="exec-progress-bar" class="progress progress-primary w-full h-3" value="0" max="100"></progress>
|
|
387
389
|
<div id="exec-log-container" class="max-h-40 overflow-y-auto font-mono text-[11px] p-3 rounded-xl bg-neutral text-neutral-content border border-neutral-focus space-y-1 select-text"></div>
|
|
388
390
|
</div>
|
|
389
391
|
<div class="modal-action pt-3 border-t border-base-200 flex justify-between items-center" id="exec-modal-buttons">
|
|
390
392
|
<form method="dialog">
|
|
391
393
|
<button id="btn-exec-cancel" class="btn btn-sm btn-ghost">Cancel</button>
|
|
392
394
|
</form>
|
|
393
395
|
<button id="btn-exec-start" type="button" class="btn btn-sm btn-error gap-1.5 shadow-sm" disabled>
|
|
394
396
|
{{{icon "sync" class="h-4 w-4"}}}
|
|
395
397
|
Confirm & Start Replication
|
|
396
398
|
</button>
|
|
397
399
|
</div>
|
|
398
400
|
</div>
|
|
399
401
|
<form method="dialog" class="modal-backdrop">
|
|
400
402
|
<button>close</button>
|
|
401
403
|
</form>
|