fix: label management - transaction safety, deletion sync, error handling
All checks were successful
Deploy to Production / Build and Deploy (push) Successful in 42s
All checks were successful
Deploy to Production / Build and Deploy (push) Successful in 42s
- Use prisma.$transaction in auto-label-creation.service with tx client - Fix DELETE /api/labels to properly JSON.parse + disconnect labelRelations - Fix PUT /api/labels rename to handle JSON labels - Graceful error handling in /api/ai/tags and /api/ai/auto-labels - Client-side label-deleted event in home-client, notes-tabs-view, label-management-dialog Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -140,6 +140,24 @@ export function HomeClient({ initialNotes, initialSettings }: HomeClientProps) {
|
||||
|
||||
useReminderCheck(notes)
|
||||
|
||||
// Listen for global label deletion and immediately update local state
|
||||
useEffect(() => {
|
||||
const handler = (e: Event) => {
|
||||
const { name } = (e as CustomEvent).detail
|
||||
if (!name) return
|
||||
const removeLabel = (note: Note) => {
|
||||
const currentLabels = note.labels || []
|
||||
const updated = currentLabels.filter((l) => l.toLowerCase() !== name.toLowerCase())
|
||||
if (updated.length === currentLabels.length) return note
|
||||
return { ...note, labels: updated.length > 0 ? updated : null }
|
||||
}
|
||||
setNotes((prev) => prev.map(removeLabel))
|
||||
setPinnedNotes((prev) => prev.map(removeLabel))
|
||||
}
|
||||
window.addEventListener('label-deleted', handler)
|
||||
return () => window.removeEventListener('label-deleted', handler)
|
||||
}, [])
|
||||
|
||||
const prevRefreshKey = useRef(refreshKey)
|
||||
|
||||
// Rechargement uniquement pour les filtres actifs (search, labels, notebook)
|
||||
|
||||
@@ -50,8 +50,12 @@ export function LabelManagementDialog(props: LabelManagementDialogProps = {}) {
|
||||
|
||||
const handleDeleteLabel = async (id: string) => {
|
||||
try {
|
||||
const labelToDelete = labels.find(l => l.id === id)
|
||||
await deleteLabel(id)
|
||||
triggerRefresh()
|
||||
if (labelToDelete) {
|
||||
window.dispatchEvent(new CustomEvent('label-deleted', { detail: { name: labelToDelete.name } }))
|
||||
}
|
||||
setConfirmDeleteId(null)
|
||||
} catch (error) {
|
||||
console.error('Failed to delete label:', error)
|
||||
|
||||
@@ -325,6 +325,24 @@ export function NotesTabsView({ notes, onEdit, currentNotebookId }: NotesTabsVie
|
||||
)
|
||||
}, [items])
|
||||
|
||||
// Listen for global label deletion and immediately update local state
|
||||
useEffect(() => {
|
||||
const handler = (e: Event) => {
|
||||
const { name } = (e as CustomEvent).detail
|
||||
if (!name) return
|
||||
setItems((prev) =>
|
||||
prev.map((note) => {
|
||||
const currentLabels = note.labels || []
|
||||
const updated = currentLabels.filter((l) => l.toLowerCase() !== name.toLowerCase())
|
||||
if (updated.length === currentLabels.length) return note
|
||||
return { ...note, labels: updated.length > 0 ? updated : null }
|
||||
})
|
||||
)
|
||||
}
|
||||
window.addEventListener('label-deleted', handler)
|
||||
return () => window.removeEventListener('label-deleted', handler)
|
||||
}, [])
|
||||
|
||||
// Scroll to top of sidebar on note change handled by NoteInlineEditor internally
|
||||
|
||||
const sensors = useSensors(
|
||||
|
||||
Reference in New Issue
Block a user