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:
@@ -7,9 +7,10 @@ import {
|
||||
Text,
|
||||
} from '@react-three/drei';
|
||||
import { Suspense, useEffect, useRef, useState } from 'react';
|
||||
import { Stack, Text as MantineText, Paper, Title, Box, CloseButton, Group, Anchor, useComputedColorScheme, Button, Modal } from '@mantine/core';
|
||||
import { Stack, Text as MantineText, Paper, Title, Box, CloseButton, Group, Anchor, useComputedColorScheme, Button } from '@mantine/core';
|
||||
import { IconTrash } from '@tabler/icons-react';
|
||||
import { notifications } from '@mantine/notifications';
|
||||
import { DeleteNodeModal } from './DeleteNodeModal';
|
||||
import { useRouter, usePathname, useSearchParams } from 'next/navigation';
|
||||
import * as THREE from 'three';
|
||||
|
||||
@@ -482,41 +483,13 @@ export function ThoughtGalaxy() {
|
||||
)}
|
||||
|
||||
{/* Delete confirmation modal */}
|
||||
<Modal
|
||||
<DeleteNodeModal
|
||||
opened={deleteConfirmOpen}
|
||||
onClose={() => setDeleteConfirmOpen(false)}
|
||||
title="Delete Node"
|
||||
centered
|
||||
zIndex={1001}
|
||||
>
|
||||
<Stack gap="md">
|
||||
<MantineText>
|
||||
Are you sure you want to delete this node? This will:
|
||||
</MantineText>
|
||||
<Stack gap="xs" ml="md">
|
||||
<MantineText size="sm">• Remove the post from Bluesky</MantineText>
|
||||
<MantineText size="sm">• Delete the node from your galaxy</MantineText>
|
||||
<MantineText size="sm" fw={600} c="red">This action cannot be undone.</MantineText>
|
||||
</Stack>
|
||||
<Group justify="flex-end" gap="sm">
|
||||
<Button
|
||||
variant="subtle"
|
||||
onClick={() => setDeleteConfirmOpen(false)}
|
||||
disabled={isDeleting}
|
||||
>
|
||||
Cancel
|
||||
</Button>
|
||||
<Button
|
||||
color="red"
|
||||
onClick={handleDeleteNode}
|
||||
loading={isDeleting}
|
||||
leftSection={<IconTrash size={16} />}
|
||||
>
|
||||
Delete Permanently
|
||||
</Button>
|
||||
</Group>
|
||||
</Stack>
|
||||
</Modal>
|
||||
onConfirm={handleDeleteNode}
|
||||
nodeTitle={selectedNode?.title || null}
|
||||
isDeleting={isDeleting}
|
||||
/>
|
||||
|
||||
<Canvas
|
||||
camera={{ position: [0, 5, 10], fov: 60 }}
|
||||
|
||||
Reference in New Issue
Block a user