Add React inventory UI with tree and node context panel
CI / basic-check (push) Has been cancelled

This commit is contained in:
Perplexity Bot
2026-08-04 19:25:39 +00:00
parent 4466e59684
commit 8b2ed677a7
7 changed files with 479 additions and 31 deletions
+78
View File
@@ -0,0 +1,78 @@
import { useEffect, useState } from 'react';
import { InventoryTree } from '../components/inventory/InventoryTree';
import { NodeContextPanel } from '../components/inventory/NodeContextPanel';
import { fetchInventoryTree, fetchNodeContext } from '../lib/inventoryApi';
import type { InventoryTreeNode, NodeContext } from '../types/inventory';
import '../components/inventory/inventory.css';
function findFirstNode(nodes: InventoryTreeNode[]): string | null {
for (const node of nodes) {
if (node.id) return node.id;
}
return null;
}
export function InventoryPage() {
const [nodes, setNodes] = useState<InventoryTreeNode[]>([]);
const [selectedId, setSelectedId] = useState<string | null>(null);
const [context, setContext] = useState<NodeContext | null>(null);
const [loadingTree, setLoadingTree] = useState(true);
const [loadingContext, setLoadingContext] = useState(false);
const [error, setError] = useState<string | null>(null);
useEffect(() => {
let active = true;
setLoadingTree(true);
fetchInventoryTree()
.then((items) => {
if (!active) return;
setNodes(items);
const first = findFirstNode(items);
setSelectedId(first);
})
.catch((err: Error) => {
if (!active) return;
setError(err.message);
})
.finally(() => {
if (active) setLoadingTree(false);
});
return () => {
active = false;
};
}, []);
useEffect(() => {
if (!selectedId) return;
let active = true;
setLoadingContext(true);
fetchNodeContext(selectedId)
.then((item) => {
if (active) setContext(item);
})
.catch((err: Error) => {
if (active) setError(err.message);
})
.finally(() => {
if (active) setLoadingContext(false);
});
return () => {
active = false;
};
}, [selectedId]);
if (loadingTree) {
return <div className="inventory-empty">Caricamento inventory...</div>;
}
if (error) {
return <div className="inventory-error">Errore inventory: {error}</div>;
}
return (
<div className="inventory-layout">
<InventoryTree nodes={nodes} selectedId={selectedId} onSelect={setSelectedId} />
<NodeContextPanel context={context} loading={loadingContext} />
</div>
);
}