From ae64b057a6b5d93907b9b6d10e63ae02e5f41333 Mon Sep 17 00:00:00 2001 From: Sosthene Date: Tue, 17 Jun 2025 17:10:50 +0200 Subject: [PATCH] Update fields --- src/components/ProcessesViewer.css | 200 ++++++++++++++++++++++++++ src/components/ProcessesViewer.tsx | 219 +++++++++++++++++++++++++++-- 2 files changed, 405 insertions(+), 14 deletions(-) diff --git a/src/components/ProcessesViewer.css b/src/components/ProcessesViewer.css index aa004c3..e93ccb9 100644 --- a/src/components/ProcessesViewer.css +++ b/src/components/ProcessesViewer.css @@ -178,3 +178,203 @@ padding: 10px; text-align: center; } + +.update-button { + padding: 8px 16px; + background-color: #4CAF50; + color: white; + border: none; + border-radius: 4px; + cursor: pointer; + font-size: 14px; +} + +.update-button:hover { + background-color: #45a049; +} + +.data-fields-container { + display: flex; + flex-direction: column; + gap: 1rem; + margin-top: 1rem; + padding: 1rem; + background-color: rgba(255, 255, 255, 0.02); + border-radius: 8px; +} + +.data-field { + display: flex; + flex-direction: column; + gap: 0.5rem; + padding: 0.75rem; + background-color: rgba(255, 255, 255, 0.04); + border: 1px solid rgba(255, 255, 255, 0.1); + border-radius: 6px; + transition: all 0.2s ease; +} + +.data-field:hover { + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2); + border-color: rgba(255, 255, 255, 0.2); +} + +.data-field-header { + display: flex; + align-items: center; + gap: 0.5rem; + color: var(--text-color); +} + +.data-type-icon, +.data-value-icon { + font-size: 1.1rem; + opacity: 0.8; +} + +.data-label { + font-weight: 500; + color: var(--text-color); +} + +.data-field-content { + display: flex; + align-items: center; + gap: 1rem; + padding-left: 2rem; + color: var(--text-color); +} + +.hash-tooltip { + cursor: help; + opacity: 0.7; + transition: opacity 0.2s ease; + color: var(--text-color); +} + +.hash-tooltip:hover { + opacity: 1; +} + +.download-button { + display: inline-flex; + align-items: center; + gap: 0.5rem; + padding: 0.5rem 1rem; + background-color: rgba(255, 255, 255, 0.1); + border: 1px solid rgba(255, 255, 255, 0.2); + border-radius: 4px; + color: var(--text-color); + font-size: 0.9rem; + cursor: pointer; + transition: all 0.2s ease; +} + +.download-button:hover { + background-color: rgba(255, 255, 255, 0.15); + border-color: rgba(255, 255, 255, 0.3); +} + +.loading-message, +.no-access-message { + padding: 1rem; + text-align: center; + color: var(--text-color); + background-color: rgba(255, 255, 255, 0.04); + border-radius: 6px; + margin: 1rem 0; +} + +.no-access-message { + color: #ff6b6b; + background-color: rgba(255, 107, 107, 0.1); +} + +.field-update-button { + display: inline-flex; + align-items: center; + justify-content: center; + padding: 0.25rem; + background: none; + border: none; + border-radius: 4px; + color: var(--text-color-muted); + cursor: pointer; + transition: all 0.2s ease; + margin-left: auto; + font-size: 1rem; +} + +.field-update-button:hover { + color: var(--primary-color); + background-color: rgba(var(--primary-color-rgb), 0.1); +} + +.field-update-button:active { + transform: scale(0.95); +} + +.edit-form { + display: flex; + flex-direction: column; + gap: 0.5rem; + width: 100%; + padding: 0.5rem; + background-color: rgba(255, 255, 255, 0.04); + border-radius: 4px; +} + +.edit-form input[type="text"], +.edit-form input[type="number"], +.edit-form select, +.edit-form textarea { + width: 100%; + padding: 0.5rem; + background-color: rgba(255, 255, 255, 0.1); + border: 1px solid rgba(255, 255, 255, 0.2); + border-radius: 4px; + color: var(--text-color); + font-size: 0.9rem; +} + +.edit-form input[type="file"] { + width: 100%; + padding: 0.5rem; + background-color: rgba(255, 255, 255, 0.1); + border: 1px solid rgba(255, 255, 255, 0.2); + border-radius: 4px; + color: var(--text-color); + font-size: 0.9rem; +} + +.edit-form textarea { + font-family: monospace; + min-height: 100px; + resize: vertical; +} + +.edit-form-actions { + display: flex; + justify-content: flex-end; + gap: 0.5rem; + margin-top: 0.5rem; +} + +.edit-form-actions button { + padding: 0.25rem 0.75rem; + background-color: rgba(255, 255, 255, 0.1); + border: 1px solid rgba(255, 255, 255, 0.2); + border-radius: 4px; + color: var(--text-color); + cursor: pointer; + transition: all 0.2s ease; +} + +.edit-form-actions button:hover { + background-color: rgba(255, 255, 255, 0.15); + border-color: rgba(255, 255, 255, 0.3); +} + +.edit-form-actions button:active { + transform: scale(0.95); +} diff --git a/src/components/ProcessesViewer.tsx b/src/components/ProcessesViewer.tsx index 46d3a39..77fa2b9 100644 --- a/src/components/ProcessesViewer.tsx +++ b/src/components/ProcessesViewer.tsx @@ -30,6 +30,13 @@ function ProcessesViewer({ processes, myProcesses, onProcessesUpdate }: Processe 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 handleFilterClick = () => { setIsFiltered(prev => !prev); @@ -62,13 +69,11 @@ function ProcessesViewer({ processes, myProcesses, onProcessesUpdate }: Processe await messageBus.isReady(); 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); } @@ -110,6 +115,195 @@ function ProcessesViewer({ processes, myProcesses, onProcessesUpdate }: Processe return '📦'; // object }; + const handleFieldUpdate = async (processId: string, stateId: string, key: string, value: any) => { + try { + const messageBus = MessageBus.getInstance(iframeUrl); + await messageBus.isReady(); + + const updateData = { + [key]: value + }; + + // First update the process + const updatedProcess = await messageBus.updateProcess(processId, stateId, updateData, [], 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'); + } + + // Then notify about the update + await messageBus.notifyProcessUpdate(processId, newStateId); + + // Finally validate the state + await messageBus.validateState(processId, newStateId); + + // Refresh the processes data + const updatedProcesses = await messageBus.getProcesses(); + if (onProcessesUpdate) { + onProcessesUpdate(updatedProcesses); + } + console.log('Process updated successfully'); + } catch (error) { + console.error('Error updating field:', error); + // You might want to show an error message to the user here + } + }; + + const renderEditForm = (key: string, value: any, onSave: (newValue: any) => void, onCancel: () => void) => { + // Initialize tempValue when editing starts + 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) { + const arrayBuffer = event.target.result as ArrayBuffer; + const uint8Array = new Uint8Array(arrayBuffer); + setTempValue({ + type: file.type, + data: uint8Array + }); + } + }; + reader.readAsArrayBuffer(file); + } + }} + /> +
+ + +
+
+ ); + } + + if (typeof value === 'boolean') { + return ( +
+ +
+ + +
+
+ ); + } + + if (Array.isArray(value)) { + return ( +
+