Display private data for each process
This commit is contained in:
parent
32d76e2328
commit
94b6e58cd0
@ -172,3 +172,9 @@
|
||||
margin-bottom: 0.25rem;
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
|
||||
.process-actions {
|
||||
margin-top: 20px;
|
||||
padding: 10px;
|
||||
text-align: center;
|
||||
}
|
||||
|
@ -1,14 +1,14 @@
|
||||
import { useState, memo } from 'react';
|
||||
import './ProcessesViewer.css';
|
||||
import { isFileBlob, type FileBlob } from '../sdk/models/Data';
|
||||
import MessageBus from '../sdk/MessageBus';
|
||||
import { iframeUrl } from '../App';
|
||||
|
||||
interface BlockState {
|
||||
commited_in: string;
|
||||
state_id: string;
|
||||
pcd_commitment: Record<string, string>;
|
||||
public_data: {
|
||||
memberPublicName?: string | number[];
|
||||
pairedAddresses?: string[] | number[];
|
||||
};
|
||||
public_data: Record<string, any>;
|
||||
// Autres propriétés disponibles si nécessaires
|
||||
}
|
||||
|
||||
@ -28,6 +28,7 @@ interface ProcessesViewerProps {
|
||||
function ProcessesViewer({ processes, myProcesses }: ProcessesViewerProps) {
|
||||
const [expandedBlocks, setExpandedBlocks] = useState<string[]>([]);
|
||||
const [isFiltered, setIsFiltered] = useState<boolean>(false);
|
||||
const [privateData, setPrivateData] = useState<Record<string, Record<string, any>>>({});
|
||||
|
||||
const handleFilterClick = () => {
|
||||
setIsFiltered(prev => !prev);
|
||||
@ -51,24 +52,49 @@ function ProcessesViewer({ processes, myProcesses }: ProcessesViewerProps) {
|
||||
);
|
||||
};
|
||||
|
||||
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;
|
||||
const fetchPrivateData = async (processId: string, stateId: string) => {
|
||||
if (!expandedBlocks.includes(processId) || !myProcesses.includes(processId)) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const messageBus = MessageBus.getInstance(iframeUrl);
|
||||
await messageBus.isReady();
|
||||
|
||||
return "Format d'adresse inconnu";
|
||||
const data = await messageBus.getData(processId, stateId);
|
||||
console.log(data);
|
||||
|
||||
setPrivateData(prev => ({
|
||||
...prev,
|
||||
[stateId]: data
|
||||
}));
|
||||
console.log(privateData);
|
||||
} catch (error) {
|
||||
console.error('Error fetching private data:', error);
|
||||
}
|
||||
};
|
||||
|
||||
const handleDownload = (name: string | undefined, fileBlob: FileBlob) => {
|
||||
const blob = new Blob([fileBlob.data], { type: fileBlob.type });
|
||||
const url = URL.createObjectURL(blob);
|
||||
const a = document.createElement('a');
|
||||
a.href = url;
|
||||
a.download = name || 'download';
|
||||
document.body.appendChild(a);
|
||||
a.click();
|
||||
document.body.removeChild(a);
|
||||
URL.revokeObjectURL(url);
|
||||
};
|
||||
|
||||
const formatValue = (key: string, value: string | number[] | FileBlob) => {
|
||||
if (isFileBlob(value)) {
|
||||
return (
|
||||
<div>
|
||||
<span>{key}</span>
|
||||
<button onClick={() => handleDownload(key, value)}>Download</button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
return JSON.stringify(value || ''); // TODO handle most common cases
|
||||
};
|
||||
|
||||
const formatName = (name: string | number[] | undefined): string => {
|
||||
@ -154,29 +180,46 @@ function ProcessesViewer({ processes, myProcesses }: ProcessesViewerProps) {
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div className="state-private-data">
|
||||
<h5>Données privées</h5>
|
||||
<div className="private-data-item">
|
||||
{!myProcesses.includes(processId) ? (
|
||||
<div className="no-data-message">
|
||||
Vous n'avez pas accès aux données privées de ce processus
|
||||
</div>
|
||||
) : !privateData[state.state_id] ? (
|
||||
(() => {
|
||||
fetchPrivateData(processId, state.state_id);
|
||||
return <div>Chargement...</div>;
|
||||
})()
|
||||
) : Object.keys(privateData[state.state_id]).length > 0 ? (
|
||||
Object.entries(privateData[state.state_id]).map(([key, value]) => (
|
||||
<div key={key}>
|
||||
<strong>{key}:</strong> {formatValue(key, value)}
|
||||
</div>
|
||||
))
|
||||
) : (
|
||||
<div className="no-data-message">
|
||||
Aucune donnée privée disponible
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<div className="state-public-data">
|
||||
<h5>Données publiques</h5>
|
||||
<div className="public-data-item">
|
||||
<strong>Nom:</strong> {formatName(state.public_data.memberPublicName)}
|
||||
{Object.keys(state.public_data).length > 0 ? (
|
||||
Object.entries(state.public_data).map(([key, value]) => (
|
||||
<div key={key}>
|
||||
<strong>{key}:</strong> {formatValue(key, value)}
|
||||
</div>
|
||||
))
|
||||
) : (
|
||||
<div className="no-data-message">
|
||||
Aucune donnée publique disponible
|
||||
</div>
|
||||
)}
|
||||
</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>
|
||||
);
|
||||
|
Loading…
x
Reference in New Issue
Block a user