feat: add confirm dialogs for delete/reset actions
This commit is contained in:
@@ -19,6 +19,14 @@ import {
|
||||
import { cn } from '@/lib/utils';
|
||||
import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip';
|
||||
import { ScrollableOverlay } from '@/components/ui/ScrollableOverlay';
|
||||
import {
|
||||
Dialog,
|
||||
DialogContent,
|
||||
DialogDescription,
|
||||
DialogFooter,
|
||||
DialogHeader,
|
||||
DialogTitle,
|
||||
} from '@/components/ui/dialog';
|
||||
|
||||
const PROFILE_COLORS = [
|
||||
{ key: 'keyword', label: 'Green', cssVar: 'var(--syntax-keyword)' },
|
||||
@@ -70,6 +78,8 @@ export const GitIdentitiesPage: React.FC = () => {
|
||||
const [color, setColor] = React.useState('keyword');
|
||||
const [icon, setIcon] = React.useState('branch');
|
||||
const [isSaving, setIsSaving] = React.useState(false);
|
||||
const [isDeleteDialogOpen, setIsDeleteDialogOpen] = React.useState(false);
|
||||
const [isDeleting, setIsDeleting] = React.useState(false);
|
||||
|
||||
React.useEffect(() => {
|
||||
if (importData) {
|
||||
@@ -152,23 +162,31 @@ export const GitIdentitiesPage: React.FC = () => {
|
||||
}
|
||||
};
|
||||
|
||||
const handleDelete = async () => {
|
||||
const handleDelete = () => {
|
||||
if (!selectedProfileId || isNewProfile) return;
|
||||
|
||||
if (!confirm('Are you sure you want to delete this profile?')) {
|
||||
setIsDeleteDialogOpen(true);
|
||||
};
|
||||
|
||||
const handleConfirmDelete = async () => {
|
||||
if (!selectedProfileId || isNewProfile) {
|
||||
return;
|
||||
}
|
||||
|
||||
setIsDeleting(true);
|
||||
try {
|
||||
const success = await deleteProfile(selectedProfileId);
|
||||
if (success) {
|
||||
toast.success('Profile deleted successfully');
|
||||
setIsDeleteDialogOpen(false);
|
||||
} else {
|
||||
toast.error('Failed to delete profile');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error deleting profile:', error);
|
||||
toast.error('An error occurred while deleting');
|
||||
} finally {
|
||||
setIsDeleting(false);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -483,6 +501,32 @@ export const GitIdentitiesPage: React.FC = () => {
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<Dialog
|
||||
open={isDeleteDialogOpen}
|
||||
onOpenChange={(open) => {
|
||||
if (!isDeleting) {
|
||||
setIsDeleteDialogOpen(open);
|
||||
}
|
||||
}}
|
||||
>
|
||||
<DialogContent className="max-w-md">
|
||||
<DialogHeader>
|
||||
<DialogTitle>Delete Profile</DialogTitle>
|
||||
<DialogDescription>
|
||||
Are you sure you want to delete profile "{selectedProfile?.name || name || 'this profile'}"?
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
<DialogFooter>
|
||||
<Button variant="ghost" onClick={() => setIsDeleteDialogOpen(false)} disabled={isDeleting}>
|
||||
Cancel
|
||||
</Button>
|
||||
<Button variant="destructive" onClick={() => void handleConfirmDelete()} disabled={isDeleting}>
|
||||
Delete
|
||||
</Button>
|
||||
</DialogFooter>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
</div>
|
||||
</ScrollableOverlay>
|
||||
);
|
||||
|
||||
@@ -1,6 +1,14 @@
|
||||
import React from 'react';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { toast } from '@/components/ui';
|
||||
import {
|
||||
Dialog,
|
||||
DialogContent,
|
||||
DialogDescription,
|
||||
DialogFooter,
|
||||
DialogHeader,
|
||||
DialogTitle,
|
||||
} from '@/components/ui/dialog';
|
||||
import {
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
@@ -49,6 +57,9 @@ interface GitIdentitiesSidebarProps {
|
||||
}
|
||||
|
||||
export const GitIdentitiesSidebar: React.FC<GitIdentitiesSidebarProps> = ({ onItemSelect }) => {
|
||||
const [deleteDialogProfile, setDeleteDialogProfile] = React.useState<GitIdentityProfile | null>(null);
|
||||
const [isDeletePending, setIsDeletePending] = React.useState(false);
|
||||
|
||||
const {
|
||||
selectedProfileId,
|
||||
defaultGitIdentityId,
|
||||
@@ -99,14 +110,23 @@ export const GitIdentitiesSidebar: React.FC<GitIdentitiesSidebarProps> = ({ onIt
|
||||
};
|
||||
|
||||
const handleDeleteProfile = async (profile: GitIdentityProfile) => {
|
||||
if (window.confirm(`Are you sure you want to delete profile "${profile.name}"?`)) {
|
||||
const success = await deleteProfile(profile.id);
|
||||
if (success) {
|
||||
toast.success(`Profile "${profile.name}" deleted successfully`);
|
||||
} else {
|
||||
toast.error('Failed to delete profile');
|
||||
}
|
||||
setDeleteDialogProfile(profile);
|
||||
};
|
||||
|
||||
const handleConfirmDeleteProfile = async () => {
|
||||
if (!deleteDialogProfile) {
|
||||
return;
|
||||
}
|
||||
|
||||
setIsDeletePending(true);
|
||||
const success = await deleteProfile(deleteDialogProfile.id);
|
||||
if (success) {
|
||||
toast.success(`Profile "${deleteDialogProfile.name}" deleted successfully`);
|
||||
setDeleteDialogProfile(null);
|
||||
} else {
|
||||
toast.error('Failed to delete profile');
|
||||
}
|
||||
setIsDeletePending(false);
|
||||
};
|
||||
|
||||
const handleToggleDefault = async (profileId: string) => {
|
||||
@@ -216,6 +236,32 @@ export const GitIdentitiesSidebar: React.FC<GitIdentitiesSidebarProps> = ({ onIt
|
||||
</>
|
||||
)}
|
||||
</ScrollableOverlay>
|
||||
|
||||
<Dialog
|
||||
open={deleteDialogProfile !== null}
|
||||
onOpenChange={(open) => {
|
||||
if (!open && !isDeletePending) {
|
||||
setDeleteDialogProfile(null);
|
||||
}
|
||||
}}
|
||||
>
|
||||
<DialogContent className="max-w-md">
|
||||
<DialogHeader>
|
||||
<DialogTitle>Delete Profile</DialogTitle>
|
||||
<DialogDescription>
|
||||
Are you sure you want to delete profile "{deleteDialogProfile?.name}"?
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
<DialogFooter>
|
||||
<Button variant="ghost" onClick={() => setDeleteDialogProfile(null)} disabled={isDeletePending}>
|
||||
Cancel
|
||||
</Button>
|
||||
<Button variant="destructive" onClick={() => void handleConfirmDeleteProfile()} disabled={isDeletePending}>
|
||||
Delete
|
||||
</Button>
|
||||
</DialogFooter>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user