forked from 1b-agent/opencadstudio-upstream
225 lines
6.9 KiB
Rust
225 lines
6.9 KiB
Rust
use crate::app::Message;
|
|
use crate::io::recovery::{RecoveryReport, RecoveryStatus};
|
|
use iced::widget::{button, column, container, row, scrollable, text, Space};
|
|
use iced::{Background, Border, Element, Fill, Theme};
|
|
|
|
fn muted_style(theme: &Theme) -> iced::widget::text::Style {
|
|
iced::widget::text::Style {
|
|
color: Some(theme.palette().background.base.text.scale_alpha(0.68)),
|
|
}
|
|
}
|
|
|
|
fn status_style(
|
|
status: RecoveryStatus,
|
|
) -> impl Fn(&Theme) -> iced::widget::text::Style + Copy {
|
|
move |theme: &Theme| iced::widget::text::Style {
|
|
color: Some(match status {
|
|
RecoveryStatus::Recovered => theme.palette().warning.base.color,
|
|
RecoveryStatus::Failed => theme.palette().danger.base.color,
|
|
}),
|
|
}
|
|
}
|
|
|
|
fn metric<'a>(label: String, value: String) -> Element<'a, Message> {
|
|
container(
|
|
column![
|
|
text(label).size(10).style(muted_style),
|
|
text(value).size(18),
|
|
]
|
|
.spacing(3),
|
|
)
|
|
.padding([10, 12])
|
|
.width(Fill)
|
|
.style(|theme: &Theme| container::Style {
|
|
background: Some(Background::Color(theme.palette().background.weak.color)),
|
|
border: Border {
|
|
color: theme.palette().background.neutral.color,
|
|
width: 1.0,
|
|
radius: 5.0.into(),
|
|
},
|
|
..Default::default()
|
|
})
|
|
.into()
|
|
}
|
|
|
|
pub fn view_window<'a>(
|
|
report: &'a RecoveryReport,
|
|
allow_save_copy: bool,
|
|
sizing: crate::ui::modal::ModalSizing,
|
|
) -> Element<'a, Message> {
|
|
let recovered = report.status == RecoveryStatus::Recovered;
|
|
let heading = if recovered {
|
|
crate::tr!("recovery-opened-with-repairs")
|
|
} else {
|
|
crate::tr!("recovery-open-failed")
|
|
};
|
|
let description = if recovered {
|
|
crate::tr!("recovery-repaired-description")
|
|
} else {
|
|
crate::tr!("recovery-failed-description")
|
|
};
|
|
let status = report.status;
|
|
|
|
let metrics = row![
|
|
metric(
|
|
crate::tr!("recovery-entities-checked"),
|
|
report.entities_scanned.to_string(),
|
|
),
|
|
metric(
|
|
crate::tr!("recovery-issues-found"),
|
|
report.issues_found().to_string(),
|
|
),
|
|
metric(
|
|
crate::tr!("recovery-entities-removed"),
|
|
report.removed_total().to_string(),
|
|
),
|
|
metric(
|
|
crate::tr!("recovery-references-checked"),
|
|
report.references_checked.to_string(),
|
|
),
|
|
]
|
|
.spacing(8)
|
|
.width(Fill);
|
|
|
|
let mut details = column![].spacing(6);
|
|
if report.referenced_entities_removed > 0 {
|
|
details = details.push(
|
|
text(format!(
|
|
"{}: {}",
|
|
crate::tr!("recovery-referenced-entities-removed"),
|
|
report.referenced_entities_removed
|
|
))
|
|
.size(11),
|
|
);
|
|
}
|
|
if report.references_missing > 0 || report.references_failed > 0 {
|
|
details = details.push(
|
|
text(format!(
|
|
"{}: {}",
|
|
crate::tr!("recovery-references-unavailable"),
|
|
report
|
|
.references_missing
|
|
.saturating_add(report.references_failed)
|
|
))
|
|
.size(11),
|
|
);
|
|
}
|
|
if let Some(error) = &report.error {
|
|
details = details.push(text(error).size(11));
|
|
}
|
|
for (kind, message) in report.diagnostics.iter().take(100) {
|
|
details = details.push(text(format!("[{kind}] {message}")).size(10));
|
|
}
|
|
if let Some(path) = &report.log_path {
|
|
details = details.push(
|
|
text(format!("{}: {}", crate::tr!("recovery-log-path"), path.display()))
|
|
.size(10)
|
|
.style(muted_style),
|
|
);
|
|
} else if let Some(error) = &report.log_error {
|
|
details = details.push(
|
|
text(format!(
|
|
"{}: {error}",
|
|
crate::tr!("recovery-log-write-failed")
|
|
))
|
|
.size(10)
|
|
.style(status_style(RecoveryStatus::Failed)),
|
|
);
|
|
} else if cfg!(target_arch = "wasm32") {
|
|
details = details.push(
|
|
text(crate::tr!("recovery-log-download-ready"))
|
|
.size(10)
|
|
.style(muted_style),
|
|
);
|
|
}
|
|
|
|
let detail_panel = container(scrollable(details).height(Fill))
|
|
.padding([10, 12])
|
|
.width(Fill)
|
|
.height(Fill)
|
|
.style(container::bordered_box);
|
|
|
|
let mut actions = row![Space::new().width(Fill)].spacing(8);
|
|
if recovered && report.save_as_required && allow_save_copy {
|
|
actions = actions.push(
|
|
button(text(crate::tr!("recovery-save-copy")).size(12))
|
|
.on_press(Message::RecoverySaveAs)
|
|
.style(button::primary)
|
|
.padding([6, 14]),
|
|
);
|
|
}
|
|
if report.log_path.is_some() || cfg!(target_arch = "wasm32") {
|
|
actions = actions.push(
|
|
button(text(crate::tr!("recovery-show-log")).size(12))
|
|
.on_press(Message::RecoveryShowLog)
|
|
.style(button::secondary)
|
|
.padding([6, 14]),
|
|
);
|
|
}
|
|
actions = actions.push(
|
|
button(text(crate::tr!("action-close")).size(12))
|
|
.on_press(Message::RecoveryClose)
|
|
.style(button::secondary)
|
|
.padding([6, 14]),
|
|
);
|
|
|
|
container(
|
|
column![
|
|
text(heading).size(20).style(status_style(status)),
|
|
text(&report.file_name).size(13),
|
|
text(description).size(11).style(muted_style),
|
|
Space::new().height(4),
|
|
metrics,
|
|
detail_panel,
|
|
actions,
|
|
]
|
|
.spacing(10)
|
|
.width(sizing.width)
|
|
.height(sizing.height),
|
|
)
|
|
.padding([12, 16])
|
|
.width(sizing.width)
|
|
.height(sizing.height)
|
|
.into()
|
|
}
|
|
|
|
pub fn view_prompt<'a>(
|
|
file_name: &'a str,
|
|
error: &'a str,
|
|
sizing: crate::ui::modal::ModalSizing,
|
|
) -> Element<'a, Message> {
|
|
let actions = row![
|
|
Space::new().width(Fill),
|
|
button(text(crate::tr!("recovery-decline")).size(12))
|
|
.on_press(Message::RecoveryDecline)
|
|
.style(button::secondary)
|
|
.padding([6, 14]),
|
|
button(text(crate::tr!("recovery-attempt")).size(12))
|
|
.on_press(Message::RecoveryAttempt)
|
|
.style(button::primary)
|
|
.padding([6, 14]),
|
|
]
|
|
.spacing(8);
|
|
|
|
container(
|
|
column![
|
|
text(crate::tr!("recovery-prompt-heading")).size(20),
|
|
text(file_name).size(13),
|
|
text(crate::tr!("recovery-prompt-description"))
|
|
.size(11)
|
|
.style(muted_style),
|
|
container(scrollable(text(error).size(10)).height(Fill))
|
|
.padding([10, 12])
|
|
.width(Fill)
|
|
.height(Fill)
|
|
.style(container::bordered_box),
|
|
actions,
|
|
]
|
|
.spacing(10)
|
|
.width(sizing.width)
|
|
.height(sizing.height),
|
|
)
|
|
.padding([12, 16])
|
|
.into()
|
|
}
|