import { useState, memo } from 'react'; import { isFileBlob, type FileBlob } from '@/lib/4nk/models/Data'; import { iframeUrl } from "@/app/page"; import MessageBus from '@/lib/4nk/MessageBus'; interface BlockState { commited_in: string; state_id: string; pcd_commitment: Record; public_data: Record; } interface Block { states: BlockState[]; } interface Processes { [key: string]: Block; } interface ProcessesViewerProps { processes: Processes | null; myProcesses: string[]; onProcessesUpdate?: (processes: Processes) => void; } const compareStates = ( currentState: BlockState, index: number, previousState?: BlockState, currentPrivateData?: Record, previousPrivateData?: Record ) => { const result: Record = {}; Object.keys(currentState.public_data).forEach(key => { const currentValue = currentState.public_data[key]; const previousValue = previousState?.public_data[key]; const isModified = index > 0 && previousValue !== undefined && JSON.stringify(currentValue) !== JSON.stringify(previousValue); result[key] = { value: currentValue, status: isModified ? 'modified' : 'unchanged', hash: currentState.pcd_commitment[key], isPrivate: false, stateId: currentState.state_id }; }); if (index === 0 && currentPrivateData) { Object.entries(currentPrivateData).forEach(([key, value]) => { result[key] = { value, status: 'unchanged', hash: currentState.pcd_commitment[key], isPrivate: true, stateId: currentState.state_id }; }); } else if (previousPrivateData) { Object.entries(previousPrivateData).forEach(([key, value]) => { result[key] = { value, status: 'unchanged', hash: previousState?.pcd_commitment[key], isPrivate: true, stateId: previousState!.state_id }; }); if (currentPrivateData) { Object.entries(currentPrivateData).forEach(([key, value]) => { result[key] = { value, status: 'modified', hash: currentState.pcd_commitment[key], isPrivate: true, stateId: currentState.state_id }; }); } } return result; }; function ProcessesViewer({ processes, myProcesses, onProcessesUpdate }: ProcessesViewerProps) { const [expandedBlocks, setExpandedBlocks] = useState([]); const [isFiltered, setIsFiltered] = useState(false); const [privateData, setPrivateData] = useState>>({}); const [editingField, setEditingField] = useState<{processId: string; stateId: string; key: string; value: any;} | null>(null); const [tempValue, setTempValue] = useState(null); const toggleBlock = (blockId: string) => { setExpandedBlocks(prev => prev.includes(blockId) ? prev.filter(id => id !== blockId) : [...prev, blockId]); }; const handleFilterClick = () => setIsFiltered(prev => !prev); if (!processes || Object.keys(processes).length === 0) { return (

Aucun processus disponible

Connectez-vous pour voir vos processus

); } const fetchPrivateData = async (processId: string, stateId: string) => { if (!expandedBlocks.includes(processId) || !myProcesses.includes(processId)) return; try { const messageBus = MessageBus.getInstance(iframeUrl); await messageBus.isReady(); const data = await messageBus.getData(processId, stateId); setPrivateData(prev => ({ ...prev, [stateId]: data })); } catch (err) { console.error(err); } }; 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 ( ); } return {JSON.stringify(value || '')}; }; const getDataIcon = (value: any) => { if (isFileBlob(value)) return '📄'; if (typeof value === 'string') return '📝'; if (typeof value === 'number') return '🔢'; if (Array.isArray(value)) return '📋'; if (typeof value === 'boolean') return '✅'; return '📦'; }; const handleFieldUpdate = async (processId: string, stateId: string, key: string, value: any) => { try { const messageBus = MessageBus.getInstance(iframeUrl); await messageBus.isReady(); const updatedProcess = await messageBus.updateProcess(processId, stateId, { [key]: value }, [], null); if (!updatedProcess) throw new Error('No updated process found'); const newStateId = updatedProcess.diffs[0]?.state_id; if (!newStateId) throw new Error('No new state id found'); await messageBus.notifyProcessUpdate(processId, newStateId); await messageBus.validateState(processId, newStateId); const updatedProcesses = await messageBus.getProcesses(); onProcessesUpdate?.(updatedProcesses); } catch (err) { console.error(err); } }; const renderEditForm = (key: string, value: any, onSave: (v: any) => void, onCancel: () => void) => { if (tempValue === null) setTempValue(value); const handleFormClick = (e: React.MouseEvent) => { e.stopPropagation(); e.preventDefault(); }; if (isFileBlob(value)) { return (
{ e.stopPropagation(); const file = e.target.files?.[0]; if (file) { const reader = new FileReader(); reader.onload = (event) => { if (event.target?.result) { setTempValue({ type: file.type, data: new Uint8Array(event.target.result as ArrayBuffer) }); } }; reader.readAsArrayBuffer(file); } }}/>
); } if (typeof value === 'boolean') { return (
); } if (Array.isArray(value)) { return (