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>
59 lines
1.4 KiB
TypeScript
59 lines
1.4 KiB
TypeScript
'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>
|
|
);
|
|
}
|