Rework file picker for SSH modal (#19020)
This PR changes the SSH modal design so its more keyboard navigation-friendly and adds the server nickname feature. Release Notes: - N/A --------- Co-authored-by: Danilo <danilo@zed.dev> Co-authored-by: Danilo Leal <67129314+danilo-leal@users.noreply.github.com>
This commit is contained in:
parent
be7b24fcf7
commit
db7417f3b5
12 changed files with 871 additions and 491 deletions
|
@ -18,6 +18,7 @@ auto_update.workspace = true
|
|||
release_channel.workspace = true
|
||||
client.workspace = true
|
||||
editor.workspace = true
|
||||
file_finder.workspace = true
|
||||
futures.workspace = true
|
||||
fuzzy.workspace = true
|
||||
gpui.workspace = true
|
||||
|
@ -36,7 +37,6 @@ smol.workspace = true
|
|||
task.workspace = true
|
||||
terminal_view.workspace = true
|
||||
ui.workspace = true
|
||||
ui_input.workspace = true
|
||||
util.workspace = true
|
||||
workspace.workspace = true
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -16,9 +16,9 @@ use schemars::JsonSchema;
|
|||
use serde::{Deserialize, Serialize};
|
||||
use settings::{Settings, SettingsSources};
|
||||
use ui::{
|
||||
div, h_flex, prelude::*, v_flex, ActiveTheme, ButtonCommon, Clickable, Color, Icon, IconButton,
|
||||
IconName, IconSize, InteractiveElement, IntoElement, Label, LabelCommon, Styled, Tooltip,
|
||||
ViewContext, VisualContext, WindowContext,
|
||||
div, h_flex, prelude::*, v_flex, ActiveTheme, Color, Icon, IconName, IconSize,
|
||||
InteractiveElement, IntoElement, Label, LabelCommon, Styled, ViewContext, VisualContext,
|
||||
WindowContext,
|
||||
};
|
||||
use workspace::{AppState, ModalView, Workspace};
|
||||
|
||||
|
@ -35,17 +35,20 @@ impl SshSettings {
|
|||
|
||||
#[derive(Clone, Default, Serialize, Deserialize, JsonSchema)]
|
||||
pub struct SshConnection {
|
||||
pub host: String,
|
||||
pub host: SharedString,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub username: Option<String>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub port: Option<u16>,
|
||||
pub projects: Vec<SshProject>,
|
||||
/// Name to use for this server in UI.
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub nickname: Option<SharedString>,
|
||||
}
|
||||
impl From<SshConnection> for SshConnectionOptions {
|
||||
fn from(val: SshConnection) -> Self {
|
||||
SshConnectionOptions {
|
||||
host: val.host,
|
||||
host: val.host.into(),
|
||||
username: val.username,
|
||||
port: val.port,
|
||||
password: None,
|
||||
|
@ -87,7 +90,10 @@ pub struct SshConnectionModal {
|
|||
}
|
||||
|
||||
impl SshPrompt {
|
||||
pub fn new(connection_options: &SshConnectionOptions, cx: &mut ViewContext<Self>) -> Self {
|
||||
pub(crate) fn new(
|
||||
connection_options: &SshConnectionOptions,
|
||||
cx: &mut ViewContext<Self>,
|
||||
) -> Self {
|
||||
let connection_string = connection_options.connection_string().into();
|
||||
Self {
|
||||
connection_string,
|
||||
|
@ -231,12 +237,57 @@ impl SshConnectionModal {
|
|||
}
|
||||
}
|
||||
|
||||
pub(crate) struct SshConnectionHeader {
|
||||
pub(crate) connection_string: SharedString,
|
||||
pub(crate) nickname: Option<SharedString>,
|
||||
}
|
||||
|
||||
impl RenderOnce for SshConnectionHeader {
|
||||
fn render(self, cx: &mut WindowContext) -> impl IntoElement {
|
||||
let theme = cx.theme();
|
||||
|
||||
let mut header_color = theme.colors().text;
|
||||
header_color.fade_out(0.96);
|
||||
|
||||
let (main_label, meta_label) = if let Some(nickname) = self.nickname {
|
||||
(nickname, Some(format!("({})", self.connection_string)))
|
||||
} else {
|
||||
(self.connection_string, None)
|
||||
};
|
||||
|
||||
h_flex()
|
||||
.p_1()
|
||||
.rounded_t_md()
|
||||
.w_full()
|
||||
.gap_2()
|
||||
.justify_center()
|
||||
.border_b_1()
|
||||
.border_color(theme.colors().border_variant)
|
||||
.bg(header_color)
|
||||
.child(Icon::new(IconName::Server).size(IconSize::XSmall))
|
||||
.child(
|
||||
h_flex()
|
||||
.gap_1()
|
||||
.child(
|
||||
Label::new(main_label)
|
||||
.size(ui::LabelSize::Small)
|
||||
.single_line(),
|
||||
)
|
||||
.children(meta_label.map(|label| {
|
||||
Label::new(label)
|
||||
.size(ui::LabelSize::Small)
|
||||
.single_line()
|
||||
.color(Color::Muted)
|
||||
})),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl Render for SshConnectionModal {
|
||||
fn render(&mut self, cx: &mut ui::ViewContext<Self>) -> impl ui::IntoElement {
|
||||
let connection_string = self.prompt.read(cx).connection_string.clone();
|
||||
let theme = cx.theme();
|
||||
let mut header_color = cx.theme().colors().text;
|
||||
header_color.fade_out(0.96);
|
||||
|
||||
let body_color = theme.colors().editor_background;
|
||||
|
||||
v_flex()
|
||||
|
@ -248,36 +299,11 @@ impl Render for SshConnectionModal {
|
|||
.border_1()
|
||||
.border_color(theme.colors().border)
|
||||
.child(
|
||||
h_flex()
|
||||
.relative()
|
||||
.p_1()
|
||||
.rounded_t_md()
|
||||
.border_b_1()
|
||||
.border_color(theme.colors().border)
|
||||
.bg(header_color)
|
||||
.justify_between()
|
||||
.child(
|
||||
div().absolute().left_0p5().top_0p5().child(
|
||||
IconButton::new("ssh-connection-cancel", IconName::ArrowLeft)
|
||||
.icon_size(IconSize::XSmall)
|
||||
.on_click(cx.listener(move |this, _, cx| {
|
||||
this.dismiss(&Default::default(), cx);
|
||||
}))
|
||||
.tooltip(|cx| Tooltip::for_action("Back", &menu::Cancel, cx)),
|
||||
),
|
||||
)
|
||||
.child(
|
||||
h_flex()
|
||||
.w_full()
|
||||
.gap_2()
|
||||
.justify_center()
|
||||
.child(Icon::new(IconName::Server).size(IconSize::XSmall))
|
||||
.child(
|
||||
Label::new(connection_string)
|
||||
.size(ui::LabelSize::Small)
|
||||
.single_line(),
|
||||
),
|
||||
),
|
||||
SshConnectionHeader {
|
||||
connection_string,
|
||||
nickname: None,
|
||||
}
|
||||
.render(cx),
|
||||
)
|
||||
.child(
|
||||
h_flex()
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue