Skip to content

Commit 1c43bad

Browse files
authored
Add delete option for project actions (#223)
Adds a delete button to the action edit dialog with a confirmation alert. Fixes #208.
1 parent 18b6590 commit 1c43bad

File tree

2 files changed

+79
-1
lines changed

2 files changed

+79
-1
lines changed

apps/web/src/components/ChatView.tsx

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1621,6 +1621,36 @@ export default function ChatView({ threadId }: ChatViewProps) {
16211621
},
16221622
[activeProject, persistProjectScripts],
16231623
);
1624+
const deleteProjectScript = useCallback(
1625+
async (scriptId: string) => {
1626+
if (!activeProject) return;
1627+
const nextScripts = activeProject.scripts.filter((script) => script.id !== scriptId);
1628+
1629+
const deletedName = activeProject.scripts.find((s) => s.id === scriptId)?.name;
1630+
1631+
try {
1632+
await persistProjectScripts({
1633+
projectId: activeProject.id,
1634+
projectCwd: activeProject.cwd,
1635+
previousScripts: activeProject.scripts,
1636+
nextScripts,
1637+
keybinding: null,
1638+
keybindingCommand: commandForProjectScript(scriptId),
1639+
});
1640+
toastManager.add({
1641+
type: "success",
1642+
title: `Deleted action "${deletedName ?? "Unknown"}"`,
1643+
});
1644+
} catch (error) {
1645+
toastManager.add({
1646+
type: "error",
1647+
title: "Could not delete action",
1648+
description: error instanceof Error ? error.message : "An unexpected error occurred.",
1649+
});
1650+
}
1651+
},
1652+
[activeProject, persistProjectScripts],
1653+
);
16241654

16251655
const handleRuntimeModeChange = useCallback(
16261656
(mode: RuntimeMode) => {
@@ -3428,6 +3458,7 @@ export default function ChatView({ threadId }: ChatViewProps) {
34283458
}}
34293459
onAddProjectScript={saveProjectScript}
34303460
onUpdateProjectScript={updateProjectScript}
3461+
onDeleteProjectScript={deleteProjectScript}
34313462
onToggleDiff={onToggleDiff}
34323463
/>
34333464
</header>
@@ -4008,6 +4039,7 @@ interface ChatHeaderProps {
40084039
onRunProjectScript: (script: ProjectScript) => void;
40094040
onAddProjectScript: (input: NewProjectScriptInput) => Promise<void>;
40104041
onUpdateProjectScript: (scriptId: string, input: NewProjectScriptInput) => Promise<void>;
4042+
onDeleteProjectScript: (scriptId: string) => Promise<void>;
40114043
onToggleDiff: () => void;
40124044
}
40134045

@@ -4027,6 +4059,7 @@ const ChatHeader = memo(function ChatHeader({
40274059
onRunProjectScript,
40284060
onAddProjectScript,
40294061
onUpdateProjectScript,
4062+
onDeleteProjectScript,
40304063
onToggleDiff,
40314064
}: ChatHeaderProps) {
40324065
return (
@@ -4059,6 +4092,7 @@ const ChatHeader = memo(function ChatHeader({
40594092
onRunScript={onRunProjectScript}
40604093
onAddScript={onAddProjectScript}
40614094
onUpdateScript={onUpdateProjectScript}
4095+
onDeleteScript={onDeleteProjectScript}
40624096
/>
40634097
)}
40644098
{activeProjectName && (

apps/web/src/components/ProjectScriptsControl.tsx

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import {
1414
SettingsIcon,
1515
WrenchIcon,
1616
} from "lucide-react";
17-
import React, { type FormEvent, type KeyboardEvent, useMemo, useState } from "react";
17+
import React, { type FormEvent, type KeyboardEvent, useCallback, useMemo, useState } from "react";
1818

1919
import {
2020
keybindingValueForCommand,
@@ -27,6 +27,15 @@ import {
2727
} from "~/projectScripts";
2828
import { shortcutLabelForCommand } from "~/keybindings";
2929
import { isMacPlatform } from "~/lib/utils";
30+
import {
31+
AlertDialog,
32+
AlertDialogClose,
33+
AlertDialogDescription,
34+
AlertDialogFooter,
35+
AlertDialogHeader,
36+
AlertDialogPopup,
37+
AlertDialogTitle,
38+
} from "./ui/alert-dialog";
3039
import { Button } from "./ui/button";
3140
import {
3241
Dialog,
@@ -84,6 +93,7 @@ interface ProjectScriptsControlProps {
8493
onRunScript: (script: ProjectScript) => void;
8594
onAddScript: (input: NewProjectScriptInput) => Promise<void> | void;
8695
onUpdateScript: (scriptId: string, input: NewProjectScriptInput) => Promise<void> | void;
96+
onDeleteScript: (scriptId: string) => Promise<void> | void;
8797
}
8898

8999
function normalizeShortcutKeyToken(key: string): string | null {
@@ -144,6 +154,7 @@ export default function ProjectScriptsControl({
144154
onRunScript,
145155
onAddScript,
146156
onUpdateScript,
157+
onDeleteScript,
147158
}: ProjectScriptsControlProps) {
148159
const addScriptFormId = React.useId();
149160
const [editingScriptId, setEditingScriptId] = useState<string | null>(null);
@@ -155,6 +166,7 @@ export default function ProjectScriptsControl({
155166
const [runOnWorktreeCreate, setRunOnWorktreeCreate] = useState(false);
156167
const [keybinding, setKeybinding] = useState("");
157168
const [validationError, setValidationError] = useState<string | null>(null);
169+
const [deleteConfirmOpen, setDeleteConfirmOpen] = useState(false);
158170

159171
const primaryScript = useMemo(() => {
160172
if (preferredScriptId) {
@@ -247,6 +259,13 @@ export default function ProjectScriptsControl({
247259
setDialogOpen(true);
248260
};
249261

262+
const confirmDeleteScript = useCallback(() => {
263+
if (!editingScriptId) return;
264+
setDeleteConfirmOpen(false);
265+
setDialogOpen(false);
266+
void onDeleteScript(editingScriptId);
267+
}, [editingScriptId, onDeleteScript]);
268+
250269
return (
251270
<>
252271
{primaryScript ? (
@@ -440,6 +459,16 @@ export default function ProjectScriptsControl({
440459
</form>
441460
</DialogPanel>
442461
<DialogFooter>
462+
{isEditing && (
463+
<Button
464+
type="button"
465+
variant="destructive-outline"
466+
className="mr-auto"
467+
onClick={() => setDeleteConfirmOpen(true)}
468+
>
469+
Delete
470+
</Button>
471+
)}
443472
<Button
444473
type="button"
445474
variant="outline"
@@ -455,6 +484,21 @@ export default function ProjectScriptsControl({
455484
</DialogFooter>
456485
</DialogPopup>
457486
</Dialog>
487+
488+
<AlertDialog open={deleteConfirmOpen} onOpenChange={setDeleteConfirmOpen}>
489+
<AlertDialogPopup>
490+
<AlertDialogHeader>
491+
<AlertDialogTitle>Delete action "{name}"?</AlertDialogTitle>
492+
<AlertDialogDescription>This action cannot be undone.</AlertDialogDescription>
493+
</AlertDialogHeader>
494+
<AlertDialogFooter>
495+
<AlertDialogClose render={<Button variant="outline" />}>Cancel</AlertDialogClose>
496+
<Button variant="destructive" onClick={confirmDeleteScript}>
497+
Delete action
498+
</Button>
499+
</AlertDialogFooter>
500+
</AlertDialogPopup>
501+
</AlertDialog>
458502
</>
459503
);
460504
}

0 commit comments

Comments
 (0)