feat: integrate ConfirmModal for delete confirmations across components

- Added `ConfirmModal` to `TaskCard`, `JiraConfigForm`, `TfsConfigForm`, and `TagsManagement` for improved user experience during delete actions.
- Replaced direct confirmation prompts with modals, enhancing UI consistency and usability.
- Updated state management to handle modal visibility and confirmation logic effectively.
This commit is contained in:
Julien Froidefond
2025-10-01 13:47:57 +02:00
parent 352a65af47
commit f13ed5b8d9
7 changed files with 299 additions and 65 deletions

View File

@@ -3,6 +3,7 @@
import { useState, useEffect } from 'react';
import { Button } from '@/components/ui/Button';
import { Badge } from '@/components/ui/Badge';
import { ConfirmModal } from '@/components/ui/ConfirmModal';
import { useJiraConfig } from '@/hooks/useJiraConfig';
import { jiraConfigClient } from '@/clients/jira-config-client';
@@ -21,6 +22,7 @@ export function JiraConfigForm() {
const [isValidating, setIsValidating] = useState(false);
const [validationResult, setValidationResult] = useState<{ type: 'success' | 'error', text: string } | null>(null);
const [message, setMessage] = useState<{ type: 'success' | 'error', text: string } | null>(null);
const [showDeleteConfirm, setShowDeleteConfirm] = useState(false);
const [showForm, setShowForm] = useState(false);
// Charger les données existantes dans le formulaire
@@ -77,10 +79,10 @@ export function JiraConfigForm() {
};
const handleDelete = async () => {
if (!confirm('Êtes-vous sûr de vouloir supprimer la configuration Jira ?')) {
return;
}
setShowDeleteConfirm(true);
};
const confirmDelete = async () => {
setIsSubmitting(true);
setMessage(null);
@@ -444,6 +446,18 @@ export function JiraConfigForm() {
{message.text}
</div>
)}
<ConfirmModal
isOpen={showDeleteConfirm}
onClose={() => setShowDeleteConfirm(false)}
onConfirm={confirmDelete}
title="Supprimer la configuration Jira"
message="Êtes-vous sûr de vouloir supprimer la configuration Jira ?"
confirmText="Supprimer"
cancelText="Annuler"
variant="destructive"
isLoading={isSubmitting}
/>
</div>
);
}

View File

@@ -5,6 +5,7 @@ import { TfsConfig } from '@/services/integrations/tfs';
import { getTfsConfig, saveTfsConfig, deleteAllTfsTasks } from '@/actions/tfs';
import { Button } from '@/components/ui/Button';
import { Badge } from '@/components/ui/Badge';
import { ConfirmModal } from '@/components/ui/ConfirmModal';
export function TfsConfigForm() {
const [config, setConfig] = useState<TfsConfig>({
@@ -24,6 +25,8 @@ export function TfsConfigForm() {
const [showForm, setShowForm] = useState(false);
const [isLoading, setIsLoading] = useState(true);
const [deletingTasks, setDeletingTasks] = useState(false);
const [showDeleteConfigConfirm, setShowDeleteConfigConfirm] = useState(false);
const [showDeleteTasksConfirm, setShowDeleteTasksConfirm] = useState(false);
// Charger la configuration existante
useEffect(() => {
@@ -85,10 +88,10 @@ export function TfsConfigForm() {
};
const handleDelete = async () => {
if (!confirm('Êtes-vous sûr de vouloir supprimer la configuration TFS ?')) {
return;
}
setShowDeleteConfigConfirm(true);
};
const confirmDeleteConfig = async () => {
startTransition(async () => {
setMessage(null);
// Réinitialiser la config
@@ -171,17 +174,10 @@ export function TfsConfigForm() {
};
const handleDeleteAllTasks = async () => {
const confirmation = confirm(
'Êtes-vous sûr de vouloir supprimer TOUTES les tâches TFS de la base locale ?\n\n' +
'Cette action est irréversible et supprimera définitivement toutes les tâches ' +
'synchronisées depuis Azure DevOps/TFS.\n\n' +
'Cliquez sur OK pour confirmer la suppression.'
);
if (!confirmation) {
return;
}
setShowDeleteTasksConfirm(true);
};
const confirmDeleteAllTasks = async () => {
try {
setDeletingTasks(true);
setMessage(null);
@@ -634,6 +630,30 @@ export function TfsConfigForm() {
{message.text}
</div>
)}
<ConfirmModal
isOpen={showDeleteConfigConfirm}
onClose={() => setShowDeleteConfigConfirm(false)}
onConfirm={confirmDeleteConfig}
title="Supprimer la configuration TFS"
message="Êtes-vous sûr de vouloir supprimer la configuration TFS ?"
confirmText="Supprimer"
cancelText="Annuler"
variant="destructive"
isLoading={isPending}
/>
<ConfirmModal
isOpen={showDeleteTasksConfirm}
onClose={() => setShowDeleteTasksConfirm(false)}
onConfirm={confirmDeleteAllTasks}
title="Supprimer toutes les tâches TFS"
message="Êtes-vous sûr de vouloir supprimer TOUTES les tâches TFS de la base locale ? Cette action est irréversible et supprimera définitivement toutes les tâches synchronisées depuis Azure DevOps/TFS."
confirmText="Supprimer définitivement"
cancelText="Annuler"
variant="destructive"
isLoading={deletingTasks}
/>
</div>
);
}

View File

@@ -4,6 +4,7 @@ import { useState, useMemo } from 'react';
import { Tag } from '@/lib/types';
import { Card, CardContent, CardHeader } from '@/components/ui/Card';
import { Button } from '@/components/ui/Button';
import { ConfirmModal } from '@/components/ui/ConfirmModal';
import { TagForm } from '@/components/forms/TagForm';
import { TagsStats } from './TagsStats';
import { TagsFilters } from './TagsFilters';
@@ -22,6 +23,8 @@ export function TagsManagement({ tags, onRefreshTags, onDeleteTag }: TagsManagem
const [isCreateModalOpen, setIsCreateModalOpen] = useState(false);
const [editingTag, setEditingTag] = useState<Tag | null>(null);
const [deletingTagId, setDeletingTagId] = useState<string | null>(null);
const [showDeleteConfirm, setShowDeleteConfirm] = useState(false);
const [tagToDelete, setTagToDelete] = useState<Tag | null>(null);
// Filtrer et trier les tags
const filteredTags = useMemo(() => {
@@ -65,18 +68,22 @@ export function TagsManagement({ tags, onRefreshTags, onDeleteTag }: TagsManagem
};
const handleDeleteTag = async (tag: Tag) => {
if (!confirm(`Êtes-vous sûr de vouloir supprimer le tag "${tag.name}" ?`)) {
return;
}
setTagToDelete(tag);
setShowDeleteConfirm(true);
};
const confirmDeleteTag = async () => {
if (!tagToDelete) return;
setDeletingTagId(tag.id);
setDeletingTagId(tagToDelete.id);
try {
await onDeleteTag(tag.id);
await onDeleteTag(tagToDelete.id);
await onRefreshTags();
} catch (error) {
console.error('Erreur lors de la suppression:', error);
} finally {
setDeletingTagId(null);
setTagToDelete(null);
}
};
@@ -164,6 +171,21 @@ export function TagsManagement({ tags, onRefreshTags, onDeleteTag }: TagsManagem
}}
/>
)}
<ConfirmModal
isOpen={showDeleteConfirm}
onClose={() => {
setShowDeleteConfirm(false);
setTagToDelete(null);
}}
onConfirm={confirmDeleteTag}
title="Supprimer le tag"
message={`Êtes-vous sûr de vouloir supprimer le tag "${tagToDelete?.name}" ?`}
confirmText="Supprimer"
cancelText="Annuler"
variant="destructive"
isLoading={!!deletingTagId}
/>
</>
);
}