mirror of
https://github.com/OFFIS-ESC/constellation-analyzer
synced 2026-01-27 07:43:41 +00:00
feat: add quick edit button for actor types in properties panel
Adds a small edit icon button next to the "Actor Type" label in the RightPanel Actor Properties section that opens the NodeTypeConfigModal directly in edit mode for the selected actor's type. Changes: - Added edit icon button aligned to the right of "Actor Type" label - Opens existing NodeTypeConfigModal in edit mode for current type - Enhanced NodeTypeConfigModal to support initialEditingTypeId prop - Modal automatically enters edit mode when opened with a type ID - Fixed TypeScript error with showAdvancedByDefault prop This provides a convenient shortcut for editing actor types without navigating to the settings menu or left panel configuration. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
a4db401ff7
commit
47957b4188
3 changed files with 79 additions and 7 deletions
|
|
@ -1,4 +1,4 @@
|
||||||
import { useState } from 'react';
|
import { useState, useEffect } from 'react';
|
||||||
import { useGraphWithHistory } from '../../hooks/useGraphWithHistory';
|
import { useGraphWithHistory } from '../../hooks/useGraphWithHistory';
|
||||||
import { useConfirm } from '../../hooks/useConfirm';
|
import { useConfirm } from '../../hooks/useConfirm';
|
||||||
import { useToastStore } from '../../stores/toastStore';
|
import { useToastStore } from '../../stores/toastStore';
|
||||||
|
|
@ -23,15 +23,29 @@ import type { NodeTypeConfig, NodeShape } from '../../types';
|
||||||
interface Props {
|
interface Props {
|
||||||
isOpen: boolean;
|
isOpen: boolean;
|
||||||
onClose: () => void;
|
onClose: () => void;
|
||||||
|
initialEditingTypeId?: string | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const NodeTypeConfigModal = ({ isOpen, onClose }: Props) => {
|
const NodeTypeConfigModal = ({ isOpen, onClose, initialEditingTypeId }: Props) => {
|
||||||
const { nodeTypes, addNodeType, updateNodeType, deleteNodeType } = useGraphWithHistory();
|
const { nodeTypes, addNodeType, updateNodeType, deleteNodeType } = useGraphWithHistory();
|
||||||
const { confirm, ConfirmDialogComponent } = useConfirm();
|
const { confirm, ConfirmDialogComponent } = useConfirm();
|
||||||
const { showToast } = useToastStore();
|
const { showToast } = useToastStore();
|
||||||
|
|
||||||
const [editingType, setEditingType] = useState<NodeTypeConfig | null>(null);
|
const [editingType, setEditingType] = useState<NodeTypeConfig | null>(null);
|
||||||
|
|
||||||
|
// Set editing type when initialEditingTypeId changes
|
||||||
|
useEffect(() => {
|
||||||
|
if (initialEditingTypeId && isOpen) {
|
||||||
|
const typeToEdit = nodeTypes.find(t => t.id === initialEditingTypeId);
|
||||||
|
if (typeToEdit) {
|
||||||
|
setEditingType(typeToEdit);
|
||||||
|
}
|
||||||
|
} else if (!isOpen) {
|
||||||
|
// Clear editing type when modal closes
|
||||||
|
setEditingType(null);
|
||||||
|
}
|
||||||
|
}, [initialEditingTypeId, isOpen, nodeTypes]);
|
||||||
|
|
||||||
const handleAddType = (type: { name: string; color: string; shape: NodeShape; icon: string; description: string }) => {
|
const handleAddType = (type: { name: string; color: string; shape: NodeShape; icon: string; description: string }) => {
|
||||||
const id = type.name.toLowerCase().replace(/\s+/g, '-');
|
const id = type.name.toLowerCase().replace(/\s+/g, '-');
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -82,7 +82,6 @@ const QuickAddTypeForm = ({ onAdd }: Props) => {
|
||||||
onKeyDown={handleKeyDown}
|
onKeyDown={handleKeyDown}
|
||||||
nameInputRef={nameInputRef}
|
nameInputRef={nameInputRef}
|
||||||
autoFocusName={false}
|
autoFocusName={false}
|
||||||
showAdvancedByDefault={false}
|
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
|
|
|
||||||
|
|
@ -7,12 +7,14 @@ import SwapHorizIcon from '@mui/icons-material/SwapHoriz';
|
||||||
import ArrowForwardIcon from '@mui/icons-material/ArrowForward';
|
import ArrowForwardIcon from '@mui/icons-material/ArrowForward';
|
||||||
import SyncAltIcon from '@mui/icons-material/SyncAlt';
|
import SyncAltIcon from '@mui/icons-material/SyncAlt';
|
||||||
import RemoveIcon from '@mui/icons-material/Remove';
|
import RemoveIcon from '@mui/icons-material/Remove';
|
||||||
|
import EditIcon from '@mui/icons-material/Edit';
|
||||||
import { usePanelStore } from '../../stores/panelStore';
|
import { usePanelStore } from '../../stores/panelStore';
|
||||||
import { useGraphWithHistory } from '../../hooks/useGraphWithHistory';
|
import { useGraphWithHistory } from '../../hooks/useGraphWithHistory';
|
||||||
import { useDocumentHistory } from '../../hooks/useDocumentHistory';
|
import { useDocumentHistory } from '../../hooks/useDocumentHistory';
|
||||||
import { useConfirm } from '../../hooks/useConfirm';
|
import { useConfirm } from '../../hooks/useConfirm';
|
||||||
import GraphMetrics from '../Common/GraphMetrics';
|
import GraphMetrics from '../Common/GraphMetrics';
|
||||||
import ConnectionDisplay from '../Common/ConnectionDisplay';
|
import ConnectionDisplay from '../Common/ConnectionDisplay';
|
||||||
|
import NodeTypeConfigModal from '../Config/NodeTypeConfig';
|
||||||
import type { Actor, Relation, EdgeDirectionality } from '../../types';
|
import type { Actor, Relation, EdgeDirectionality } from '../../types';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -80,6 +82,10 @@ const RightPanel = ({ selectedNode, selectedEdge, onClose }: Props) => {
|
||||||
const [hasNodeChanges, setHasNodeChanges] = useState(false);
|
const [hasNodeChanges, setHasNodeChanges] = useState(false);
|
||||||
const [hasEdgeChanges, setHasEdgeChanges] = useState(false);
|
const [hasEdgeChanges, setHasEdgeChanges] = useState(false);
|
||||||
|
|
||||||
|
// Actor type modal state
|
||||||
|
const [showActorTypeModal, setShowActorTypeModal] = useState(false);
|
||||||
|
const [editingActorTypeId, setEditingActorTypeId] = useState<string | null>(null);
|
||||||
|
|
||||||
// Update state when selected node changes
|
// Update state when selected node changes
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (selectedNode) {
|
if (selectedNode) {
|
||||||
|
|
@ -204,6 +210,19 @@ const RightPanel = ({ selectedNode, selectedEdge, onClose }: Props) => {
|
||||||
setEdges(updatedEdges);
|
setEdges(updatedEdges);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Handle edit actor type
|
||||||
|
const handleEditActorType = () => {
|
||||||
|
if (!actorType) return;
|
||||||
|
setEditingActorTypeId(actorType);
|
||||||
|
setShowActorTypeModal(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Handle close actor type modal
|
||||||
|
const handleCloseActorTypeModal = () => {
|
||||||
|
setShowActorTypeModal(false);
|
||||||
|
setEditingActorTypeId(null);
|
||||||
|
};
|
||||||
|
|
||||||
// Get connections for selected node
|
// Get connections for selected node
|
||||||
const getNodeConnections = () => {
|
const getNodeConnections = () => {
|
||||||
if (!selectedNode) return [];
|
if (!selectedNode) return [];
|
||||||
|
|
@ -225,6 +244,11 @@ const RightPanel = ({ selectedNode, selectedEdge, onClose }: Props) => {
|
||||||
</IconButton>
|
</IconButton>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
{ConfirmDialogComponent}
|
{ConfirmDialogComponent}
|
||||||
|
<NodeTypeConfigModal
|
||||||
|
isOpen={showActorTypeModal}
|
||||||
|
onClose={handleCloseActorTypeModal}
|
||||||
|
initialEditingTypeId={editingActorTypeId}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -239,6 +263,11 @@ const RightPanel = ({ selectedNode, selectedEdge, onClose }: Props) => {
|
||||||
<PanelHeader title="Graph Analysis" onCollapse={collapseRightPanel} />
|
<PanelHeader title="Graph Analysis" onCollapse={collapseRightPanel} />
|
||||||
<GraphMetrics nodes={nodes} edges={edges} />
|
<GraphMetrics nodes={nodes} edges={edges} />
|
||||||
{ConfirmDialogComponent}
|
{ConfirmDialogComponent}
|
||||||
|
<NodeTypeConfigModal
|
||||||
|
isOpen={showActorTypeModal}
|
||||||
|
onClose={handleCloseActorTypeModal}
|
||||||
|
initialEditingTypeId={editingActorTypeId}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -258,9 +287,20 @@ const RightPanel = ({ selectedNode, selectedEdge, onClose }: Props) => {
|
||||||
<div className="flex-1 overflow-y-auto overflow-x-hidden px-3 py-3 space-y-4">
|
<div className="flex-1 overflow-y-auto overflow-x-hidden px-3 py-3 space-y-4">
|
||||||
{/* Actor Type */}
|
{/* Actor Type */}
|
||||||
<div>
|
<div>
|
||||||
<label className="block text-xs font-medium text-gray-700 mb-1">
|
<div className="flex items-center justify-between mb-1">
|
||||||
Actor Type
|
<label className="block text-xs font-medium text-gray-700">
|
||||||
</label>
|
Actor Type
|
||||||
|
</label>
|
||||||
|
<Tooltip title="Edit Actor Type">
|
||||||
|
<IconButton
|
||||||
|
size="small"
|
||||||
|
onClick={handleEditActorType}
|
||||||
|
sx={{ padding: '2px' }}
|
||||||
|
>
|
||||||
|
<EditIcon sx={{ fontSize: 14 }} />
|
||||||
|
</IconButton>
|
||||||
|
</Tooltip>
|
||||||
|
</div>
|
||||||
<select
|
<select
|
||||||
value={actorType}
|
value={actorType}
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
|
|
@ -406,6 +446,11 @@ const RightPanel = ({ selectedNode, selectedEdge, onClose }: Props) => {
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
{ConfirmDialogComponent}
|
{ConfirmDialogComponent}
|
||||||
|
<NodeTypeConfigModal
|
||||||
|
isOpen={showActorTypeModal}
|
||||||
|
onClose={handleCloseActorTypeModal}
|
||||||
|
initialEditingTypeId={editingActorTypeId}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -587,11 +632,25 @@ const RightPanel = ({ selectedNode, selectedEdge, onClose }: Props) => {
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
{ConfirmDialogComponent}
|
{ConfirmDialogComponent}
|
||||||
|
<NodeTypeConfigModal
|
||||||
|
isOpen={showActorTypeModal}
|
||||||
|
onClose={handleCloseActorTypeModal}
|
||||||
|
initialEditingTypeId={editingActorTypeId}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return (
|
||||||
|
<>
|
||||||
|
{ConfirmDialogComponent}
|
||||||
|
<NodeTypeConfigModal
|
||||||
|
isOpen={showActorTypeModal}
|
||||||
|
onClose={handleCloseActorTypeModal}
|
||||||
|
initialEditingTypeId={editingActorTypeId}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default RightPanel;
|
export default RightPanel;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue