Allow extensions to be filtered on installed and not installed (#8375)

Partially resolves: https://github.com/zed-industries/zed/issues/7785

Right now, we can engage `Only show installed`, but I've been wanting to
be able to filter down to just uninstalled extensions too, so I can
browse things I don't have. I changed this to have 2 checkboxes,
`Installed` and `Not installed` and both are on by default. You deselect
them to filter down.

<img width="1608" alt="SCR-20240225-etyg"
src="https://github.com/zed-industries/zed/assets/19867440/e2267651-ff86-437b-ba59-89f3d338ea02">

Release Notes:

- Allow extensions list to be filtered down to both installed and not
installed.
This commit is contained in:
Joseph T. Lyons 2024-02-25 05:07:13 -05:00 committed by GitHub
parent 882cd6e52f
commit 633e31a47f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -34,7 +34,8 @@ pub struct ExtensionsPage {
list: UniformListScrollHandle,
telemetry: Arc<Telemetry>,
is_fetching_extensions: bool,
is_only_showing_installed_extensions: bool,
is_showing_installed_extensions: bool,
is_showing_not_installed_extensions: bool,
extension_entries: Vec<Extension>,
query_editor: View<Editor>,
query_contains_error: bool,
@ -55,7 +56,8 @@ impl ExtensionsPage {
list: UniformListScrollHandle::new(),
telemetry: workspace.client().telemetry().clone(),
is_fetching_extensions: false,
is_only_showing_installed_extensions: false,
is_showing_installed_extensions: true,
is_showing_not_installed_extensions: true,
extension_entries: Vec::new(),
query_contains_error: false,
extension_fetch_task: None,
@ -73,12 +75,16 @@ impl ExtensionsPage {
self.extension_entries
.iter()
.filter(|extension| {
if self.is_only_showing_installed_extensions {
let status = extension_store.extension_status(&extension.id);
let status = extension_store.extension_status(&extension.id);
matches!(status, ExtensionStatus::Installed(_))
} else {
true
match [
self.is_showing_installed_extensions,
self.is_showing_not_installed_extensions,
] {
[true, true] => true,
[true, false] => matches!(status, ExtensionStatus::Installed(_)),
[false, true] => matches!(status, ExtensionStatus::NotInstalled),
[false, false] => false,
}
})
.cloned()
@ -415,19 +421,15 @@ impl ExtensionsPage {
}
fn render_empty_state(&self, cx: &mut ViewContext<Self>) -> impl IntoElement {
let has_search = self.search_query(cx).is_some();
let is_filtering = self.search_query(cx).is_some()
|| self.is_showing_installed_extensions
|| self.is_showing_not_installed_extensions;
let message = if self.is_fetching_extensions {
"Loading extensions..."
} else if self.is_only_showing_installed_extensions {
if has_search {
"No installed extensions that match your search."
} else {
"No installed extensions."
}
} else {
if has_search {
"No extensions that match your search."
if is_filtering {
"No extensions that match your search criteria."
} else {
"No extensions."
}
@ -455,15 +457,31 @@ impl Render for ExtensionsPage {
.gap_2()
.child(h_flex().child(self.render_search(cx)))
.child(CheckboxWithLabel::new(
"installed",
Label::new("Only show installed"),
if self.is_only_showing_installed_extensions {
"Installed",
Label::new("Installed"),
if self.is_showing_installed_extensions {
Selection::Selected
} else {
Selection::Unselected
},
cx.listener(|this, selection, _cx| {
this.is_only_showing_installed_extensions = match selection {
this.is_showing_installed_extensions = match selection {
Selection::Selected => true,
Selection::Unselected => false,
Selection::Indeterminate => return,
}
}),
))
.child(CheckboxWithLabel::new(
"not installed",
Label::new("Not installed"),
if self.is_showing_not_installed_extensions {
Selection::Selected
} else {
Selection::Unselected
},
cx.listener(|this, selection, _cx| {
this.is_showing_not_installed_extensions = match selection {
Selection::Selected => true,
Selection::Unselected => false,
Selection::Indeterminate => return,