Files
RuDS/crates/bds-ui/src/views/metadata_diff.rs

158 lines
5.6 KiB
Rust

use iced::widget::text::Shaping;
use iced::widget::{Space, button, column, container, row, scrollable, text};
use iced::{Color, Element, Length};
use bds_core::engine::metadata_diff::{DiffReport, RepairDirection};
use bds_core::i18n::UiLocale;
use crate::app::Message;
use crate::components::inputs;
use crate::i18n::{t, tw};
#[derive(Debug, Clone, Default)]
pub struct MetadataDiffState {
pub is_running: bool,
pub is_repairing: bool,
pub report: Option<DiffReport>,
pub error_message: Option<String>,
}
pub fn view<'a>(state: &'a MetadataDiffState, locale: UiLocale) -> Element<'a, Message> {
let run = button(text(t(locale, "metadataDiff.run")).size(13))
.on_press_maybe(
(!state.is_running && !state.is_repairing).then_some(Message::RunMetadataDiff),
)
.style(inputs::primary_button)
.padding([6, 16]);
let mut content = column![
row![
text(t(locale, "tabBar.metadataDiff"))
.size(24)
.shaping(Shaping::Advanced)
.color(Color::from_rgb(0.88, 0.88, 0.92)),
Space::with_width(Length::Fill),
run,
]
.align_y(iced::Alignment::Center),
]
.spacing(16);
if state.is_running {
content = content.push(message_card(t(locale, "metadataDiff.running")));
} else if let Some(error) = &state.error_message {
content = content.push(message_card(error.clone()));
} else if let Some(report) = &state.report {
if report.diffs.is_empty() && report.orphans.is_empty() && report.errors.is_empty() {
content = content.push(message_card(t(locale, "metadataDiff.clean")));
}
for (index, item) in report.diffs.iter().enumerate() {
let fields = item
.fields
.iter()
.fold(column!().spacing(4), |column, field| {
column.push(
text(tw(
locale,
"metadataDiff.field",
&[
("field", &field.field_name),
("database", &field.db_value),
("file", &field.file_value),
],
))
.size(12)
.color(Color::from_rgb(0.72, 0.72, 0.78)),
)
});
let actions = row![
button(text(t(locale, "metadataDiff.fileToDb")).size(12))
.on_press_maybe((!state.is_repairing).then_some(
Message::RepairMetadataDiffItem {
index,
direction: RepairDirection::FileToDatabase,
},
))
.style(inputs::secondary_button)
.padding([5, 10]),
button(text(t(locale, "metadataDiff.dbToFile")).size(12))
.on_press_maybe((!state.is_repairing).then_some(
Message::RepairMetadataDiffItem {
index,
direction: RepairDirection::DatabaseToFile,
},
))
.style(inputs::secondary_button)
.padding([5, 10]),
]
.spacing(8);
content = content.push(inputs::card(
column![
text(tw(
locale,
"metadataDiff.entity",
&[("entity", &item.entity_type), ("path", &item.file_path)],
))
.size(15)
.color(Color::from_rgb(0.86, 0.86, 0.92)),
fields,
actions,
]
.spacing(10),
));
}
if !report.orphans.is_empty() {
let rows = report
.orphans
.iter()
.fold(column!().spacing(4), |column, orphan| {
column.push(
text(tw(
locale,
"metadataDiff.orphan",
&[("reason", &orphan.reason), ("path", &orphan.file_path)],
))
.size(12),
)
});
content = content.push(inputs::card(
column![text(t(locale, "metadataDiff.orphans")).size(16), rows].spacing(8),
));
}
if !report.errors.is_empty() {
content = content.push(inputs::card(
column![
text(t(locale, "metadataDiff.errors")).size(16),
report
.errors
.iter()
.fold(column!().spacing(4), |column, error| {
column.push(text(error.clone()).size(12))
}),
]
.spacing(8),
));
}
} else {
content = content.push(message_card(t(locale, "metadataDiff.idle")));
}
container(
scrollable(content)
.direction(scrollable::Direction::Vertical(inputs::compact_scrollbar()))
.style(inputs::scrollable_style),
)
.width(Length::Fill)
.height(Length::Fill)
.padding(24)
.into()
}
fn message_card(value: String) -> Element<'static, Message> {
inputs::card(
text(value)
.size(14)
.color(Color::from_rgb(0.66, 0.66, 0.72)),
)
.into()
}