Iteration 4a: rebuild command with confirmation modal
Adds the explicit `rebuild` app-level command (ADR-0015 §7, §11)
and a modal UI infrastructure to host its confirmation dialog.
Typing `rebuild` emits Action::PrepareRebuild; the runtime reads
project.yaml + data/ to compute a summary ("3 tables and 47 rows
will be reconstructed; the existing playground.db will be
replaced") and posts AppEvent::RebuildPrepared, which opens the
modal. Y confirms, N/Esc cancels. While the modal is open,
normal input is gated.
The worker's do_rebuild_from_text now wipes existing user tables
and metadata before reloading from text, so it works on both
fresh and populated databases. Source text is plumbed through
rebuild_from_text so the explicit rebuild logs to history.log
while the silent on-load rebuild from Iteration 3 stays silent.
Modal infrastructure (App.modal field + key routing + centered
overlay rendering + word-wrap) is reused by Iteration 4b's save
/ save as / load / new flows.
Tests: 314 passing (268 lib + 9 + 5 + 6 new + 9 + 17),
0 failing, 0 skipped. Clippy clean.
This commit is contained in:
@@ -69,7 +69,7 @@ fn rebuild_restores_schema_only_project() {
|
||||
)
|
||||
.unwrap();
|
||||
rt().block_on(async {
|
||||
db.rebuild_from_text(project.path().to_path_buf())
|
||||
db.rebuild_from_text(project.path().to_path_buf(), None)
|
||||
.await
|
||||
.expect("rebuild");
|
||||
});
|
||||
@@ -137,7 +137,7 @@ fn rebuild_restores_rows_from_csv() {
|
||||
)
|
||||
.unwrap();
|
||||
rt().block_on(async {
|
||||
db.rebuild_from_text(project.path().to_path_buf())
|
||||
db.rebuild_from_text(project.path().to_path_buf(), None)
|
||||
.await
|
||||
.expect("rebuild");
|
||||
});
|
||||
@@ -226,7 +226,7 @@ fn rebuild_restores_relationships_and_cascade_behaviour() {
|
||||
)
|
||||
.unwrap();
|
||||
rt().block_on(async {
|
||||
db.rebuild_from_text(project.path().to_path_buf())
|
||||
db.rebuild_from_text(project.path().to_path_buf(), None)
|
||||
.await
|
||||
.expect("rebuild");
|
||||
});
|
||||
@@ -303,7 +303,7 @@ fn rebuild_reports_fatal_error_on_bad_csv_row() {
|
||||
.unwrap();
|
||||
let err = rt()
|
||||
.block_on(async {
|
||||
db.rebuild_from_text(project.path().to_path_buf()).await
|
||||
db.rebuild_from_text(project.path().to_path_buf(), None).await
|
||||
})
|
||||
.expect_err("must fail with row-level error");
|
||||
let msg = format!("{err}");
|
||||
@@ -363,7 +363,7 @@ fn rebuild_preserves_created_at_from_yaml() {
|
||||
)
|
||||
.unwrap();
|
||||
rt().block_on(async {
|
||||
db.rebuild_from_text(project.path().to_path_buf())
|
||||
db.rebuild_from_text(project.path().to_path_buf(), None)
|
||||
.await
|
||||
.expect("rebuild");
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user