Add Save button to task edit dialog - changes only save when clicked
This commit is contained in:
parent
33d8822b45
commit
1db22ef509
@ -91,12 +91,20 @@ export default function Home() {
|
||||
const [newComment, setNewComment] = useState("")
|
||||
const [editingTask, setEditingTask] = useState<Task | null>(null)
|
||||
const [viewMode, setViewMode] = useState<'kanban' | 'backlog'>('kanban')
|
||||
const [editedTask, setEditedTask] = useState<Task | null>(null)
|
||||
|
||||
// Sync from server on mount
|
||||
useEffect(() => {
|
||||
syncFromServer()
|
||||
}, [syncFromServer])
|
||||
|
||||
// Set editedTask when selectedTask changes
|
||||
useEffect(() => {
|
||||
if (selectedTask) {
|
||||
setEditedTask({ ...selectedTask })
|
||||
}
|
||||
}, [selectedTask])
|
||||
|
||||
const selectedProject = projects.find((p) => p.id === selectedProjectId)
|
||||
const selectedTask = tasks.find((t) => t.id === selectedTaskId)
|
||||
const projectTasks = selectedProjectId ? getTasksByProject(selectedProjectId) : []
|
||||
@ -528,47 +536,41 @@ export default function Home() {
|
||||
</Dialog>
|
||||
|
||||
{/* Task Detail Dialog with Comments */}
|
||||
<Dialog open={!!selectedTaskId} onOpenChange={() => selectTask(null)}>
|
||||
<Dialog open={!!selectedTaskId} onOpenChange={() => {
|
||||
selectTask(null)
|
||||
setEditedTask(null)
|
||||
}}>
|
||||
<DialogContent className="bg-slate-900 border-slate-800 text-white w-[95vw] max-w-2xl max-h-[90vh] overflow-y-auto p-4 md:p-6">
|
||||
{selectedTask && (
|
||||
{selectedTask && editedTask && (
|
||||
<>
|
||||
<DialogHeader>
|
||||
<div className="flex items-center gap-2 mb-2">
|
||||
<Badge className={`${typeColors[selectedTask.type]} text-white border-0`}>
|
||||
{typeLabels[selectedTask.type]}
|
||||
<Badge className={`${typeColors[editedTask.type]} text-white border-0`}>
|
||||
{typeLabels[editedTask.type]}
|
||||
</Badge>
|
||||
<Badge variant="outline" className={priorityColors[selectedTask.priority]}>
|
||||
{selectedTask.priority}
|
||||
<Badge variant="outline" className={priorityColors[editedTask.priority]}>
|
||||
{editedTask.priority}
|
||||
</Badge>
|
||||
</div>
|
||||
<DialogTitle className="text-xl">{selectedTask.title}</DialogTitle>
|
||||
<input
|
||||
type="text"
|
||||
value={editedTask.title}
|
||||
onChange={(e) => setEditedTask({ ...editedTask, title: e.target.value })}
|
||||
className="w-full text-xl font-semibold bg-slate-800 border border-slate-700 rounded px-3 py-2 text-white"
|
||||
/>
|
||||
</DialogHeader>
|
||||
|
||||
<div className="space-y-6 py-4">
|
||||
{/* Description */}
|
||||
{selectedTask.description && (
|
||||
<div>
|
||||
<Label className="text-slate-400">Description</Label>
|
||||
<p className="mt-2 text-slate-300 whitespace-pre-wrap">
|
||||
{selectedTask.description}
|
||||
</p>
|
||||
<textarea
|
||||
value={editedTask.description || ""}
|
||||
onChange={(e) => setEditedTask({ ...editedTask, description: e.target.value })}
|
||||
rows={3}
|
||||
className="w-full mt-2 px-3 py-2 bg-slate-800 border border-slate-700 rounded-lg text-white"
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Tags */}
|
||||
{selectedTask.tags.length > 0 && (
|
||||
<div>
|
||||
<Label className="text-slate-400">Tags</Label>
|
||||
<div className="flex flex-wrap gap-2 mt-2">
|
||||
{selectedTask.tags.map((tag) => (
|
||||
<Badge key={tag} variant="secondary" className="bg-slate-800 text-slate-300">
|
||||
<Tag className="w-3 h-3 mr-1" />
|
||||
{tag}
|
||||
</Badge>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Priority */}
|
||||
<div>
|
||||
@ -577,9 +579,9 @@ export default function Home() {
|
||||
{(["low", "medium", "high", "urgent"] as Priority[]).map((priority) => (
|
||||
<button
|
||||
key={priority}
|
||||
onClick={() => updateTask(selectedTask.id, { priority })}
|
||||
onClick={() => setEditedTask({ ...editedTask, priority })}
|
||||
className={`px-3 py-1.5 rounded-lg text-sm transition-colors capitalize ${
|
||||
selectedTask.priority === priority
|
||||
editedTask.priority === priority
|
||||
? priority === "urgent"
|
||||
? "bg-red-600 text-white"
|
||||
: priority === "high"
|
||||
@ -600,8 +602,8 @@ export default function Home() {
|
||||
<div>
|
||||
<Label className="text-slate-400">Status</Label>
|
||||
<select
|
||||
value={selectedTask.status}
|
||||
onChange={(e) => handleUpdateTaskStatus(selectedTask.id, e.target.value as TaskStatus)}
|
||||
value={editedTask.status}
|
||||
onChange={(e) => setEditedTask({ ...editedTask, status: e.target.value as TaskStatus })}
|
||||
className="w-full mt-2 px-3 py-2 bg-slate-800 border border-slate-700 rounded-lg text-white focus:outline-none focus:border-blue-500"
|
||||
>
|
||||
{allStatuses.map((status) => (
|
||||
@ -614,8 +616,8 @@ export default function Home() {
|
||||
<div>
|
||||
<Label className="text-slate-400">Sprint</Label>
|
||||
<select
|
||||
value={selectedTask.sprintId || ""}
|
||||
onChange={(e) => updateTask(selectedTask.id, { sprintId: e.target.value || undefined })}
|
||||
value={editedTask.sprintId || ""}
|
||||
onChange={(e) => setEditedTask({ ...editedTask, sprintId: e.target.value || undefined })}
|
||||
className="w-full mt-2 px-3 py-2 bg-slate-800 border border-slate-700 rounded-lg text-white focus:outline-none focus:border-blue-500"
|
||||
>
|
||||
<option value="">No Sprint</option>
|
||||
@ -631,15 +633,15 @@ export default function Home() {
|
||||
<div className="border-t border-slate-800 pt-6">
|
||||
<h4 className="font-medium text-white mb-4 flex items-center gap-2">
|
||||
<MessageSquare className="w-4 h-4" />
|
||||
Notes & Comments ({selectedTask.comments.length})
|
||||
Notes & Comments ({editedTask.comments.length})
|
||||
</h4>
|
||||
|
||||
{/* Comment List */}
|
||||
<div className="space-y-4 mb-4">
|
||||
{selectedTask.comments.length === 0 ? (
|
||||
{editedTask.comments.length === 0 ? (
|
||||
<p className="text-slate-500 text-sm">No notes yet. Add the first one!</p>
|
||||
) : (
|
||||
selectedTask.comments.map((comment) => (
|
||||
editedTask.comments.map((comment) => (
|
||||
<div
|
||||
key={comment.id}
|
||||
className={`flex gap-3 p-3 rounded-lg ${
|
||||
@ -707,15 +709,25 @@ export default function Home() {
|
||||
onClick={() => {
|
||||
deleteTask(selectedTask.id)
|
||||
selectTask(null)
|
||||
setEditedTask(null)
|
||||
}}
|
||||
>
|
||||
<Trash2 className="w-4 h-4 mr-2" />
|
||||
Delete Task
|
||||
</Button>
|
||||
<div className="flex items-center gap-3">
|
||||
<span className="text-sm text-slate-500">Changes saved automatically</span>
|
||||
<Button onClick={() => selectTask(null)}>
|
||||
Close
|
||||
<Button variant="ghost" onClick={() => {
|
||||
selectTask(null)
|
||||
setEditedTask(null)
|
||||
}}>
|
||||
Cancel
|
||||
</Button>
|
||||
<Button onClick={() => {
|
||||
updateTask(editedTask.id, editedTask)
|
||||
selectTask(null)
|
||||
setEditedTask(null)
|
||||
}}>
|
||||
Save Changes
|
||||
</Button>
|
||||
</div>
|
||||
</DialogFooter>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user