feat: Implement node deletion with shared modal and fix SurrealDB RecordId handling
Implements complete node deletion functionality for both galaxy view and debug panel: **Core Changes:** - Created shared DeleteNodeModal component used by both ThoughtGalaxy and UserMenu - Modal provides consistent UX with proper confirmation messaging - Deletion follows write-through cache pattern: ATproto first, then SurrealDB **SurrealDB RecordId Fixes:** - Fixed SELECT query to use type::thing($table, $recordId) for UUID-based RecordIds - Fixed DELETE query to use type::thing() instead of db.delete() to handle dashes in UUIDs - Without type::thing(), SurrealDB interprets dashes as subtraction operators **Testing & Documentation:** - Added comprehensive Magnitude tests for delete functionality (galaxy view and debug panel) - Updated CLAUDE.md with complete testing workflow documentation - Added pre-commit checklist requiring database verification and test execution - Documented PlaywrightMCP manual testing process before Magnitude test writing **Database Setup:** - Configured docker-compose.yml to use environment variables for credentials - Updated namespace/database to match .env configuration (ponderants/main) **File Changes:** - app/api/nodes/[id]/route.ts: Fixed RecordId query patterns (SELECT and DELETE) - components/DeleteNodeModal.tsx: New shared modal component - components/ThoughtGalaxy.tsx: Uses shared DeleteNodeModal - components/UserMenu.tsx: Replaced browser confirm() with shared DeleteNodeModal - tests/magnitude/03-delete-node.mag.ts: Added debug panel delete test - AGENTS.md: Added testing workflow and pre-commit checklist documentation - docker-compose.yml: Environment variable configuration 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
58
components/DeleteNodeModal.tsx
Normal file
58
components/DeleteNodeModal.tsx
Normal file
@@ -0,0 +1,58 @@
|
||||
'use client';
|
||||
|
||||
import { Modal, Stack, Text, Group, Button } from '@mantine/core';
|
||||
import { IconTrash } from '@tabler/icons-react';
|
||||
|
||||
interface DeleteNodeModalProps {
|
||||
opened: boolean;
|
||||
onClose: () => void;
|
||||
onConfirm: () => void;
|
||||
nodeTitle: string | null;
|
||||
isDeleting: boolean;
|
||||
}
|
||||
|
||||
export function DeleteNodeModal({
|
||||
opened,
|
||||
onClose,
|
||||
onConfirm,
|
||||
nodeTitle,
|
||||
isDeleting,
|
||||
}: DeleteNodeModalProps) {
|
||||
return (
|
||||
<Modal
|
||||
opened={opened}
|
||||
onClose={onClose}
|
||||
title="Delete Node"
|
||||
centered
|
||||
zIndex={1001}
|
||||
>
|
||||
<Stack gap="md">
|
||||
<Text>
|
||||
Are you sure you want to delete "{nodeTitle}"? This will:
|
||||
</Text>
|
||||
<Stack gap="xs" ml="md">
|
||||
<Text size="sm">• Remove the post from Bluesky</Text>
|
||||
<Text size="sm">• Delete the node from your galaxy</Text>
|
||||
<Text size="sm" fw={600} c="red">This action cannot be undone.</Text>
|
||||
</Stack>
|
||||
<Group justify="flex-end" gap="sm">
|
||||
<Button
|
||||
variant="subtle"
|
||||
onClick={onClose}
|
||||
disabled={isDeleting}
|
||||
>
|
||||
Cancel
|
||||
</Button>
|
||||
<Button
|
||||
color="red"
|
||||
onClick={onConfirm}
|
||||
loading={isDeleting}
|
||||
leftSection={<IconTrash size={16} />}
|
||||
>
|
||||
Delete Permanently
|
||||
</Button>
|
||||
</Group>
|
||||
</Stack>
|
||||
</Modal>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user