feat: preserve nested source projects across desktop and REST
This commit is contained in:
@@ -7,6 +7,7 @@ use iced::{
|
||||
Element as View, Fill, Font,
|
||||
widget::{
|
||||
self, Space, button, column, container, pick_list, row, scrollable, text, text_input,
|
||||
tooltip,
|
||||
},
|
||||
};
|
||||
use oa_core::*;
|
||||
@@ -1080,7 +1081,7 @@ fn source_files(app: &App) -> View<'_, Message> {
|
||||
);
|
||||
}
|
||||
}
|
||||
let mut panel = column![
|
||||
let panel = column![
|
||||
text("SOURCE FILES").size(13),
|
||||
label(format!(
|
||||
"{} files · one system model",
|
||||
@@ -1097,9 +1098,6 @@ fn source_files(app: &App) -> View<'_, Message> {
|
||||
label("Includes define file membership. Closing a detached buffer never deletes its file."),
|
||||
]
|
||||
.spacing(9);
|
||||
if app.pending_recovery.is_some() {
|
||||
panel = panel.push(action("Recover interrupted save", Message::SourceRecover));
|
||||
}
|
||||
panel.into()
|
||||
}
|
||||
|
||||
@@ -1144,8 +1142,49 @@ fn source(app: &App) -> View<'_, Message> {
|
||||
} else {
|
||||
column![].into()
|
||||
};
|
||||
let recovery: View<'_, Message> = if let Some(path) = &app.pending_recovery {
|
||||
let edits_block_recovery =
|
||||
!app.source_workspace.applied && app.source_workspace.has_edits();
|
||||
let filename = path.file_name().unwrap_or_default().to_string_lossy();
|
||||
container(
|
||||
column![
|
||||
tooltip(
|
||||
text(format!("Interrupted save · {filename}")).size(15),
|
||||
text(path.display().to_string()).size(12),
|
||||
tooltip::Position::Bottom,
|
||||
),
|
||||
text(if edits_block_recovery {
|
||||
"Revert the edited files before recovery. Recovery restores files to their state before the interrupted save, then reopens them."
|
||||
} else if app.source_workspace.applied {
|
||||
"Restore files to their state before the interrupted save. Your current model and editor drafts are kept."
|
||||
} else {
|
||||
"Restore files to their state before the interrupted save, then reopen them. This rolls back the incomplete save."
|
||||
})
|
||||
.size(13),
|
||||
button(text("Recover interrupted save").size(12))
|
||||
.padding(10)
|
||||
.on_press_maybe(
|
||||
(!edits_block_recovery && !app.busy).then_some(Message::SourceRecover),
|
||||
),
|
||||
]
|
||||
.spacing(8),
|
||||
)
|
||||
.padding(12)
|
||||
.width(Fill)
|
||||
.style(style::card)
|
||||
.into()
|
||||
} else {
|
||||
column![].into()
|
||||
};
|
||||
let mut diagnostics = column![].spacing(5);
|
||||
let mut visible_diagnostics = 0;
|
||||
for (index, issue) in app.source_diagnostics.iter().enumerate() {
|
||||
// The persistent recovery banner supplies the action and explanation;
|
||||
// repeating the internal journal path obscures ordinary diagnostics.
|
||||
if app.pending_recovery.is_some() && issue.diagnostic.code == "pending_save" {
|
||||
continue;
|
||||
}
|
||||
visible_diagnostics += 1;
|
||||
diagnostics = diagnostics.push(
|
||||
button(
|
||||
text(format!(
|
||||
@@ -1216,8 +1255,11 @@ fn source(app: &App) -> View<'_, Message> {
|
||||
]
|
||||
.spacing(7)
|
||||
.align_y(iced::Center),
|
||||
recovery,
|
||||
text(app.source_workspace.active.clone()).font(Font::MONOSPACE).size(12).color(style::INK),
|
||||
label(if !app.source_workspace.applied {
|
||||
label(if app.pending_recovery.is_some() && !app.source_workspace.applied {
|
||||
"The previous graphical model remains available while these files are recovered."
|
||||
} else if !app.source_workspace.applied {
|
||||
"This project needs repair. Apply all adopts it; the previous graphical model remains available."
|
||||
} else if app.source_workspace.detached_dirty() {
|
||||
"A detached file has an unsaved draft. Reattach it or revert that file before saving."
|
||||
@@ -1226,7 +1268,7 @@ fn source(app: &App) -> View<'_, Message> {
|
||||
}),
|
||||
navigation,
|
||||
scrollable(diagnostics)
|
||||
.height((app.source_diagnostics.len() as f32 * 32.).min(132.))
|
||||
.height((visible_diagnostics as f32 * 32.).min(132.))
|
||||
]
|
||||
.spacing(12)
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user