163 lines
5.6 KiB
TypeScript
163 lines
5.6 KiB
TypeScript
import { useState, memo } from 'react';
|
|
import './ProcessesViewer.css';
|
|
|
|
interface BlockState {
|
|
commited_in: string;
|
|
state_id: string;
|
|
public_data: {
|
|
memberPublicName?: string | number[];
|
|
pairedAddresses?: string[] | number[];
|
|
};
|
|
// Autres propriétés disponibles si nécessaires
|
|
}
|
|
|
|
interface Block {
|
|
states: BlockState[];
|
|
}
|
|
|
|
interface Processes {
|
|
[key: string]: Block;
|
|
}
|
|
|
|
interface ProcessesViewerProps {
|
|
processes: Processes | null;
|
|
}
|
|
|
|
function ProcessesViewer({ processes }: ProcessesViewerProps) {
|
|
const [expandedBlocks, setExpandedBlocks] = useState<string[]>([]);
|
|
|
|
// Si pas de données, afficher un message
|
|
if (!processes || Object.keys(processes).length === 0) {
|
|
return (
|
|
<div className="processes-viewer-empty">
|
|
<h3>Aucun processus disponible</h3>
|
|
<p>Connectez-vous</p>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
const toggleBlock = (blockId: string) => {
|
|
setExpandedBlocks(prev =>
|
|
prev.includes(blockId)
|
|
? prev.filter(id => id !== blockId)
|
|
: [...prev, blockId]
|
|
);
|
|
};
|
|
|
|
const formatAddress = (address: string | number[] | undefined): string => {
|
|
if (!address) return "Adresse non disponible";
|
|
|
|
if (Array.isArray(address)) {
|
|
// Si c'est un tableau de nombres, on le convertit en chaîne de caractères
|
|
try {
|
|
// Convertir les codes ASCII en caractères
|
|
const chars = address.map(code => String.fromCharCode(Number(code)));
|
|
return chars.join('');
|
|
} catch (e) {
|
|
return "Adresse encodée (format non supporté)";
|
|
}
|
|
} else if (typeof address === 'string') {
|
|
// Si c'est déjà une chaîne, on la retourne telle quelle
|
|
return address;
|
|
}
|
|
|
|
return "Format d'adresse inconnu";
|
|
};
|
|
|
|
const formatName = (name: string | number[] | undefined): string => {
|
|
if (!name) return "Nom non disponible";
|
|
|
|
if (Array.isArray(name)) {
|
|
if (name.length === 1 && name[0] === 96) {
|
|
return "`"; // Caractère spécial
|
|
}
|
|
try {
|
|
const chars = name.map(code => String.fromCharCode(Number(code)));
|
|
return chars.join('');
|
|
} catch (e) {
|
|
return "Nom encodé (format non supporté)";
|
|
}
|
|
} else if (typeof name === 'string') {
|
|
return name;
|
|
}
|
|
|
|
return "Format de nom inconnu";
|
|
};
|
|
|
|
return (
|
|
<div className="processes-viewer">
|
|
<h2>Processus</h2>
|
|
<p className="block-count">{Object.keys(processes).length} processus disponible(s)</p>
|
|
|
|
<div className="block-list">
|
|
{Object.entries(processes).map(([blockId, block]) => {
|
|
const isExpanded = expandedBlocks.includes(blockId);
|
|
const stateCount = block.states.length;
|
|
// Le premier état est le plus récent
|
|
|
|
return (
|
|
<div key={blockId} className="block-item">
|
|
<div
|
|
className={`block-header ${isExpanded ? 'expanded' : ''}`}
|
|
onClick={() => toggleBlock(blockId)}
|
|
>
|
|
<div className="block-id">{blockId.substring(0, 8)}...{blockId.substring(blockId.length - 4)}</div>
|
|
<div className="block-state-count">{stateCount} état(s)</div>
|
|
<div className="block-toggle">{isExpanded ? '▼' : '▶'}</div>
|
|
</div>
|
|
|
|
{isExpanded && (
|
|
<div className="block-details">
|
|
<div className="block-complete-id">
|
|
<strong>ID complet:</strong> {blockId}
|
|
</div>
|
|
|
|
{block.states.map((state, index) => (
|
|
<div key={`${blockId}-state-${index}`} className="state-item">
|
|
<h4>État {index + 1}</h4>
|
|
<div className="state-detail">
|
|
<strong>State ID:</strong> {state.state_id}
|
|
</div>
|
|
<div className="state-detail">
|
|
<strong>Commited dans:</strong> {state.commited_in}
|
|
</div>
|
|
|
|
<div className="state-public-data">
|
|
<h5>Données publiques</h5>
|
|
<div className="public-data-item">
|
|
<strong>Nom:</strong> {formatName(state.public_data.memberPublicName)}
|
|
</div>
|
|
{state.public_data.pairedAddresses && (
|
|
<div className="public-data-item">
|
|
<strong>Adresses associées:</strong>
|
|
<ul className="address-list">
|
|
{Array.isArray(state.public_data.pairedAddresses) ?
|
|
(typeof state.public_data.pairedAddresses[0] === 'string' ? (
|
|
(state.public_data.pairedAddresses as string[]).map((addr, i) => (
|
|
<li key={i}>{addr}</li>
|
|
))
|
|
) : (
|
|
<li>{formatAddress(state.public_data.pairedAddresses as number[])}</li>
|
|
)) : (
|
|
<li>{String(state.public_data.pairedAddresses || '')}</li>
|
|
)
|
|
}
|
|
</ul>
|
|
</div>
|
|
)}
|
|
</div>
|
|
</div>
|
|
))}
|
|
</div>
|
|
)}
|
|
</div>
|
|
);
|
|
})}
|
|
</div>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
ProcessesViewer.displayName = 'ProcessesViewer';
|
|
export default memo(ProcessesViewer);
|