project panel: Add git clone action to empty state (#36371)

This PR adds the git clone action to the project panel. It also changes
the "open" button to open a folder instead of the recent projects modal,
which feels faster to start with, more intuitive, and also consistent
with VS Code (which I think is good in this specific case).

<img width="500" height="1334" alt="CleanShot 2025-08-17 at 2  10 01@2x"
src="https://github.com/user-attachments/assets/ff953228-9e8e-413b-89ba-fa0870a0df17"
/>

Release Notes:

- Improved the project panel empty state by including the git clone
action and allowing users to quickly open a local folder.
This commit is contained in:
Danilo Leal 2025-08-17 14:27:42 -03:00 committed by GitHub
parent 46a2d8d95a
commit 8282b9cf00
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 33 additions and 10 deletions

View file

@ -37,7 +37,7 @@ const CONTENT: (Section<4>, Section<3>) = (
}, },
SectionEntry { SectionEntry {
icon: IconName::CloudDownload, icon: IconName::CloudDownload,
title: "Clone a Repo", title: "Clone Repository",
action: &git::Clone, action: &git::Clone,
}, },
SectionEntry { SectionEntry {

View file

@ -57,9 +57,9 @@ use std::{
}; };
use theme::ThemeSettings; use theme::ThemeSettings;
use ui::{ use ui::{
Color, ContextMenu, DecoratedIcon, Icon, IconDecoration, IconDecorationKind, IndentGuideColors, Color, ContextMenu, DecoratedIcon, Divider, Icon, IconDecoration, IconDecorationKind,
IndentGuideLayout, KeyBinding, Label, LabelSize, ListItem, ListItemSpacing, ScrollableHandle, IndentGuideColors, IndentGuideLayout, KeyBinding, Label, LabelSize, ListItem, ListItemSpacing,
Scrollbar, ScrollbarState, StickyCandidate, Tooltip, prelude::*, v_flex, ScrollableHandle, Scrollbar, ScrollbarState, StickyCandidate, Tooltip, prelude::*, v_flex,
}; };
use util::{ResultExt, TakeUntilExt, TryFutureExt, maybe, paths::compare_paths}; use util::{ResultExt, TakeUntilExt, TryFutureExt, maybe, paths::compare_paths};
use workspace::{ use workspace::{
@ -69,7 +69,6 @@ use workspace::{
notifications::{DetachAndPromptErr, NotifyTaskExt}, notifications::{DetachAndPromptErr, NotifyTaskExt},
}; };
use worktree::CreatedEntry; use worktree::CreatedEntry;
use zed_actions::OpenRecent;
const PROJECT_PANEL_KEY: &str = "ProjectPanel"; const PROJECT_PANEL_KEY: &str = "ProjectPanel";
const NEW_ENTRY_ID: ProjectEntryId = ProjectEntryId::MAX; const NEW_ENTRY_ID: ProjectEntryId = ProjectEntryId::MAX;
@ -5521,24 +5520,48 @@ impl Render for ProjectPanel {
.with_priority(3) .with_priority(3)
})) }))
} else { } else {
let focus_handle = self.focus_handle(cx).clone();
v_flex() v_flex()
.id("empty-project_panel") .id("empty-project_panel")
.size_full()
.p_4() .p_4()
.size_full()
.items_center()
.justify_center()
.gap_1()
.track_focus(&self.focus_handle(cx)) .track_focus(&self.focus_handle(cx))
.child( .child(
Button::new("open_project", "Open a project") Button::new("open_project", "Open Project")
.full_width() .full_width()
.key_binding(KeyBinding::for_action_in( .key_binding(KeyBinding::for_action_in(
&OpenRecent::default(), &workspace::Open,
&self.focus_handle, &focus_handle,
window, window,
cx, cx,
)) ))
.on_click(cx.listener(|this, _, window, cx| { .on_click(cx.listener(|this, _, window, cx| {
this.workspace this.workspace
.update(cx, |_, cx| { .update(cx, |_, cx| {
window.dispatch_action(OpenRecent::default().boxed_clone(), cx); window.dispatch_action(workspace::Open.boxed_clone(), cx);
})
.log_err();
})),
)
.child(
h_flex()
.w_1_2()
.gap_2()
.child(Divider::horizontal())
.child(Label::new("or").size(LabelSize::XSmall).color(Color::Muted))
.child(Divider::horizontal()),
)
.child(
Button::new("clone_repo", "Clone Repository")
.full_width()
.on_click(cx.listener(|this, _, window, cx| {
this.workspace
.update(cx, |_, cx| {
window.dispatch_action(git::Clone.boxed_clone(), cx);
}) })
.log_err(); .log_err();
})), })),