settings_ui: Add confirmation prompt before deleting a skill (#61044)
Previously, clicking the trash icon on the Skills settings page
immediately moved the skill's directory to the trash.
This PR now shows a confirmation prompt explains what will be deleted
and where it's shared before anything is moved to the trash. This is
because that directory is shared with other agent tools
(`~/.agents/skills` or `{project}/.agents/skills`), deleting it silently
affects more than just Zed, I think it's better to explain that.
<img height="250" alt="global-skill-delete"
src="https://github.com/user-attachments/assets/d49ecc92-c195-42d2-924e-6fb9d024d2ec"
/>
<img height="250" alt="project-skill-delete"
src="https://github.com/user-attachments/assets/4b84af28-b8fd-4635-afe5-c1cd73d09e1a"
/>
Release Notes:
- Added a confirmation prompt when deleting skills from the settings
window.
This commit is contained in:
1 parent
919ec316f3
commit
7862fff55c
1 file changed
+47
-6
@@ -1,9 +1,10 @@
|
||||
use agent_skills::{Skill, SkillIndex, encode_skill_share_link};
|
||||
use agent_skills::{Skill, SkillIndex, SkillSource, encode_skill_share_link};
|
||||
use fs::RemoveOptions;
|
||||
use gpui::{App, ClipboardItem, ScrollHandle, SharedString, prelude::*};
|
||||
use gpui::{App, ClipboardItem, PromptLevel, ScrollHandle, SharedString, prelude::*};
|
||||
|
||||
use ui::{Divider, Tooltip, prelude::*};
|
||||
use util::ResultExt as _;
|
||||
use util::paths::PathExt as _;
|
||||
|
||||
use crate::pages::SkillCreatorOpenMode;
|
||||
use crate::{SettingsUiFile, SettingsWindow};
|
||||
@@ -115,6 +116,12 @@ fn render_skill_row(
|
||||
) -> AnyElement {
|
||||
let skill_file_path = skill.skill_file_path.clone();
|
||||
let directory_path = skill.directory_path.clone();
|
||||
let skill_name = skill.name.clone();
|
||||
|
||||
let (skill_scope, shared_scope) = match &skill.source {
|
||||
SkillSource::ProjectLocal { .. } => ("project", "used in this project"),
|
||||
_ => ("global", "on this machine"),
|
||||
};
|
||||
|
||||
let share_copied = settings_window.last_copied_skill_directory_path.as_deref()
|
||||
== Some(skill.directory_path.as_path());
|
||||
@@ -214,19 +221,53 @@ fn render_skill_row(
|
||||
.icon_size(IconSize::Small)
|
||||
.tooltip(Tooltip::text("Delete Skill"))
|
||||
.on_click(cx.listener(
|
||||
move |settings_window, _event, _window, cx| {
|
||||
move |settings_window, _event, window, cx| {
|
||||
let directory_path = directory_path.clone();
|
||||
if !settings_window
|
||||
if settings_window
|
||||
.hidden_deleted_skill_directory_paths
|
||||
.insert(directory_path.clone())
|
||||
.contains(&directory_path)
|
||||
{
|
||||
return;
|
||||
}
|
||||
cx.notify();
|
||||
|
||||
let prompt_message =
|
||||
format!("Delete the {skill_scope} skill \"{skill_name}\"?");
|
||||
let prompt_detail = format!(
|
||||
"This will move {} to the trash. This skill is shared with other \
|
||||
agent tools {shared_scope}, so it will no longer be available to \
|
||||
them either.",
|
||||
directory_path.compact().display(),
|
||||
);
|
||||
let answer = window.prompt(
|
||||
PromptLevel::Info,
|
||||
&prompt_message,
|
||||
Some(&prompt_detail),
|
||||
&["Delete", "Cancel"],
|
||||
cx,
|
||||
);
|
||||
|
||||
let app_state = workspace::AppState::global(cx);
|
||||
let fs = app_state.fs.clone();
|
||||
cx.spawn(async move |settings_window, cx| {
|
||||
if answer.await != Ok(0) {
|
||||
return;
|
||||
}
|
||||
|
||||
let confirmed = settings_window
|
||||
.update(cx, |settings_window, cx| {
|
||||
let inserted = settings_window
|
||||
.hidden_deleted_skill_directory_paths
|
||||
.insert(directory_path.clone());
|
||||
if inserted {
|
||||
cx.notify();
|
||||
}
|
||||
inserted
|
||||
})
|
||||
.unwrap_or(false);
|
||||
if !confirmed {
|
||||
return;
|
||||
}
|
||||
|
||||
let trash_result = fs
|
||||
.trash(
|
||||
&directory_path,
|
||||
|
||||
Reference in new issue
Block a user