settings_ui: Show migration banner (#41112)
Closes #ISSUE Release Notes: - N/A *or* Added/Fixed/Improved ... --------- Co-authored-by: Danilo <danilo@zed.dev>
This commit is contained in:
@@ -1139,6 +1139,7 @@ impl SettingsUiFile {
|
||||
settings::SettingsFile::Project(location) => SettingsUiFile::Project(location),
|
||||
settings::SettingsFile::Server => SettingsUiFile::Server("todo: server name"),
|
||||
settings::SettingsFile::Default => return None,
|
||||
settings::SettingsFile::Global => return None,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1730,7 +1731,10 @@ impl SettingsWindow {
|
||||
let prev_files = self.files.clone();
|
||||
let settings_store = cx.global::<SettingsStore>();
|
||||
let mut ui_files = vec![];
|
||||
let all_files = settings_store.get_all_files();
|
||||
let mut all_files = settings_store.get_all_files();
|
||||
if !all_files.contains(&settings::SettingsFile::User) {
|
||||
all_files.push(settings::SettingsFile::User);
|
||||
}
|
||||
for file in all_files {
|
||||
let Some(settings_ui_file) = SettingsUiFile::from_settings(file) else {
|
||||
continue;
|
||||
@@ -2685,40 +2689,72 @@ impl SettingsWindow {
|
||||
if let Some(error) =
|
||||
SettingsStore::global(cx).error_for_file(self.current_file.to_settings())
|
||||
{
|
||||
if self.shown_errors.insert(error.clone()) {
|
||||
telemetry::event!("Settings Error Shown", error = &error);
|
||||
}
|
||||
|
||||
warning_banner = v_flex()
|
||||
.pb_4()
|
||||
.child(
|
||||
Banner::new()
|
||||
.severity(Severity::Warning)
|
||||
.child(
|
||||
v_flex()
|
||||
.my_0p5()
|
||||
.gap_0p5()
|
||||
.child(Label::new("Your settings file is in an invalid state."))
|
||||
.child(
|
||||
Label::new(error).size(LabelSize::Small).color(Color::Muted),
|
||||
),
|
||||
)
|
||||
.action_slot(
|
||||
div().pr_1().child(
|
||||
Button::new("fix-in-json", "Fix in settings.json")
|
||||
.tab_index(0_isize)
|
||||
.style(ButtonStyle::Tinted(ui::TintColor::Warning))
|
||||
.on_click(cx.listener(|this, _, _, cx| {
|
||||
this.open_current_settings_file(cx);
|
||||
})),
|
||||
),
|
||||
fn banner(
|
||||
label: &'static str,
|
||||
error: String,
|
||||
shown_errors: &mut HashSet<String>,
|
||||
cx: &mut Context<SettingsWindow>,
|
||||
) -> impl IntoElement {
|
||||
if shown_errors.insert(error.clone()) {
|
||||
telemetry::event!("Settings Error Shown", label = label, error = &error);
|
||||
}
|
||||
Banner::new()
|
||||
.severity(Severity::Warning)
|
||||
.child(
|
||||
v_flex()
|
||||
.my_0p5()
|
||||
.gap_0p5()
|
||||
.child(Label::new(label))
|
||||
.child(Label::new(error).size(LabelSize::Small).color(Color::Muted)),
|
||||
)
|
||||
.action_slot(
|
||||
div().pr_1().child(
|
||||
Button::new("fix-in-json", "Fix in settings.json")
|
||||
.tab_index(0_isize)
|
||||
.style(ButtonStyle::Tinted(ui::TintColor::Warning))
|
||||
.on_click(cx.listener(|this, _, _, cx| {
|
||||
this.open_current_settings_file(cx);
|
||||
})),
|
||||
),
|
||||
)
|
||||
)
|
||||
}
|
||||
let parse_error = error.parse_error();
|
||||
let parse_failed = parse_error.is_some();
|
||||
warning_banner = v_flex()
|
||||
.gap_2()
|
||||
.pb_4()
|
||||
.when_some(parse_error, |this, err| {
|
||||
this.child(banner(
|
||||
"Failed to load your settings. Some values may be incorrect and changes may be lost.",
|
||||
err,
|
||||
&mut self.shown_errors,
|
||||
cx,
|
||||
))
|
||||
})
|
||||
.map(|this| match &error.migration_status {
|
||||
settings::MigrationStatus::Succeeded => this.child(banner(
|
||||
"Your settings are out of date, and need to be updated.",
|
||||
match &self.current_file {
|
||||
SettingsUiFile::User => "They can be automatically migrated to the latest version.",
|
||||
SettingsUiFile::Server(_) | SettingsUiFile::Project(_) => "They must be manually migrated to the latest version."
|
||||
}.to_string(),
|
||||
&mut self.shown_errors,
|
||||
cx,
|
||||
)),
|
||||
settings::MigrationStatus::Failed { error: err } if !parse_failed => this
|
||||
.child(banner(
|
||||
"Your settings file is out of date, automatic migration failed",
|
||||
err.clone(),
|
||||
&mut self.shown_errors,
|
||||
cx,
|
||||
)),
|
||||
_ => this,
|
||||
})
|
||||
.into_any_element()
|
||||
}
|
||||
|
||||
return v_flex()
|
||||
.id("Settings-ui-page")
|
||||
.id("settings-ui-page")
|
||||
.on_action(cx.listener(|this, _: &menu::SelectNext, window, cx| {
|
||||
if !sub_page_stack().is_empty() {
|
||||
window.focus_next();
|
||||
@@ -2789,8 +2825,8 @@ impl SettingsWindow {
|
||||
.pt_6()
|
||||
.px_8()
|
||||
.bg(cx.theme().colors().editor_background)
|
||||
.child(warning_banner)
|
||||
.child(page_header)
|
||||
.child(warning_banner)
|
||||
.child(
|
||||
div()
|
||||
.size_full()
|
||||
|
||||
Reference in New Issue
Block a user