sync: contextual substrate UX from private repo
- Add DimensionIconsContext for app-wide dimension icon sharing - Enhanced getNodeIcon() with favicon/YouTube/PDF detection + dimension icons - Propagate dynamic icons to GridView, ListView, SearchModal, FocusPanel, ViewsOverlay, FolderViewOverlay - Add RahEdge component with hover labels for map edges - Update RahNode with dimension-colored borders and icon support - Add MiniMap with dimension color coding to MapPane - MCP server: add description field to rah_update_node, bump standalone to v1.4.2 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
d6987a3dc1
commit
d723212ed3
@@ -1,7 +1,8 @@
|
||||
"use client";
|
||||
|
||||
import { Node } from '@/types/database';
|
||||
import { File } from 'lucide-react';
|
||||
import { getNodeIcon } from '@/utils/nodeIcons';
|
||||
import { useDimensionIcons } from '@/context/DimensionIconsContext';
|
||||
|
||||
interface GridViewProps {
|
||||
nodes: Node[];
|
||||
@@ -9,6 +10,7 @@ interface GridViewProps {
|
||||
}
|
||||
|
||||
export default function GridView({ nodes, onNodeClick }: GridViewProps) {
|
||||
const { dimensionIcons } = useDimensionIcons();
|
||||
const truncateContent = (content?: string, maxLength: number = 120) => {
|
||||
if (!content) return '';
|
||||
if (content.length <= maxLength) return content;
|
||||
@@ -85,7 +87,7 @@ export default function GridView({ nodes, onNodeClick }: GridViewProps) {
|
||||
borderRadius: '6px',
|
||||
flexShrink: 0
|
||||
}}>
|
||||
<File size={14} color="#666" />
|
||||
{getNodeIcon(node, dimensionIcons, 14)}
|
||||
</div>
|
||||
<div style={{
|
||||
fontSize: '13px',
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
"use client";
|
||||
|
||||
import { Node } from '@/types/database';
|
||||
import { File } from 'lucide-react';
|
||||
import { getNodeIcon } from '@/utils/nodeIcons';
|
||||
import { useDimensionIcons } from '@/context/DimensionIconsContext';
|
||||
|
||||
interface ListViewProps {
|
||||
nodes: Node[];
|
||||
@@ -9,6 +10,7 @@ interface ListViewProps {
|
||||
}
|
||||
|
||||
export default function ListView({ nodes, onNodeClick }: ListViewProps) {
|
||||
const { dimensionIcons } = useDimensionIcons();
|
||||
const formatDate = (dateString?: string) => {
|
||||
if (!dateString) return '';
|
||||
const date = new Date(dateString);
|
||||
@@ -84,7 +86,7 @@ export default function ListView({ nodes, onNodeClick }: ListViewProps) {
|
||||
borderRadius: '6px',
|
||||
flexShrink: 0
|
||||
}}>
|
||||
<File size={16} color="#666" />
|
||||
{getNodeIcon(node, dimensionIcons, 16)}
|
||||
</div>
|
||||
|
||||
{/* Content */}
|
||||
|
||||
@@ -5,6 +5,7 @@ import { Plus, Trash2, LayoutGrid, List, Columns3, Save, Filter, ChevronDown, X
|
||||
import type { Node } from '@/types/database';
|
||||
import InputDialog from '../common/InputDialog';
|
||||
import { getNodeIcon } from '@/utils/nodeIcons';
|
||||
import { useDimensionIcons } from '@/context/DimensionIconsContext';
|
||||
|
||||
type ViewMode = 'grid' | 'list' | 'kanban';
|
||||
|
||||
@@ -39,6 +40,7 @@ interface ViewsOverlayProps {
|
||||
}
|
||||
|
||||
export default function ViewsOverlay({ onNodeClick, onNodeOpenInOtherPane, refreshToken = 0 }: ViewsOverlayProps) {
|
||||
const { dimensionIcons } = useDimensionIcons();
|
||||
// Dimensions for filter picker
|
||||
const [dimensions, setDimensions] = useState<DimensionSummary[]>([]);
|
||||
const [dimensionsLoading, setDimensionsLoading] = useState(true);
|
||||
@@ -401,7 +403,7 @@ export default function ViewsOverlay({ onNodeClick, onNodeOpenInOtherPane, refre
|
||||
|
||||
// Render node card
|
||||
const renderNodeCard = (node: Node, columnId?: string, dimension?: string) => {
|
||||
const nodeIcon = getNodeIcon(node);
|
||||
const nodeIcon = getNodeIcon(node, dimensionIcons);
|
||||
|
||||
return (
|
||||
<div
|
||||
|
||||
Reference in New Issue
Block a user