Multiuser system initiated with log recording

This commit is contained in:
2026-05-27 14:27:31 +08:00
parent 2b4bb5ea64
commit 1c2a0647cb
9 changed files with 619 additions and 11 deletions
+41 -4
View File
@@ -1784,6 +1784,14 @@
setLogs(prev => [...prev.slice(-80), { time: new Date().toLocaleTimeString(), message }]);
}, []);
const recordUserAction = useCallback((action, payload = {}) => {
fetch('/api/logs', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ action, ...payload })
}).catch(() => {});
}, []);
const syncCompositePlacement = useCallback((projectName, compositeName, mode = 'add') => {
setStandaloneComposites(prev => {
if (mode === 'add') return prev.filter(name => name !== compositeName);
@@ -1915,13 +1923,21 @@
const handleDelete = useCallback(() => {
if (!activePage) return;
const selectedNodeIds = new Set(activePage.nodes.filter(n => n.selected && n.id !== 'page-port').map(n => n.id));
const selectedNodes = activePage.nodes.filter(n => n.selected && n.id !== 'page-port');
const selectedNodeIds = new Set(selectedNodes.map(n => n.id));
if (selectedNodeIds.size > 0) {
const newNodes = activePage.nodes.filter(n => !selectedNodeIds.has(n.id));
const newEdges = activePage.edges.filter(e => !selectedNodeIds.has(e.source) && !selectedNodeIds.has(e.target));
setPages(prev => prev.map(p => p.id === activePage.id ? { ...p, nodes: newNodes, edges: newEdges } : p));
recordUserAction('instance.delete', {
project: currentProjectName,
cell: activePage.name,
detail: {
instances: selectedNodes.map(node => node.data?.componentDisplayName || node.id)
}
});
}
}, [activePage]);
}, [activePage, currentProjectName, recordUserAction]);
useEffect(() => {
const handleKeyDown = (e) => {
@@ -2479,7 +2495,8 @@
...prev,
[currentProjectName]: [...(prev[currentProjectName] || []), cellName]
}));
}, [pages, currentProjectName]);
recordUserAction('canvas.create', { project: currentProjectName, cell: cellName });
}, [pages, currentProjectName, recordUserAction]);
const closePage = useCallback((pageId) => {
setPages(prev => {
@@ -2616,6 +2633,11 @@
};
});
}
recordUserAction('instance.create', {
project: currentProjectName,
cell: activePage?.name,
detail: { component: parsedData.name, instance: newNode.data.componentDisplayName, type: 'standaloneComposite' }
});
return;
}
if (parsedData.type === 'composite') {
@@ -2653,6 +2675,11 @@
};
});
}
recordUserAction('instance.create', {
project: currentProjectName,
cell: activePage?.name,
detail: { component: parsedData.name, instance: newNode.data.componentDisplayName, type: 'composite' }
});
return;
}
if (!activePageId) {
@@ -2690,6 +2717,11 @@
if (p.id !== activePageId) return p;
return { ...p, nodes: p.nodes.concat(newNode) };
}));
recordUserAction('instance.create', {
project: currentProjectName,
cell: activePage?.name,
detail: { component: selectedComponent, instance: componentDisplayName, category: parsedData.category }
});
return;
}
const componentDisplayName = generateComponentDisplayName();
@@ -2709,7 +2741,12 @@
if (p.id !== activePageId) return p;
return { ...p, nodes: p.nodes.concat(newNode) };
}));
}, [activePageId, activePage, openPage, reactFlowInstance, generateComponentDisplayName, syncCompositePlacement]);
recordUserAction('instance.create', {
project: currentProjectName,
cell: activePage?.name,
detail: { component: parsedData.name, instance: componentDisplayName, category: parsedData.category }
});
}, [activePageId, activePage, openPage, reactFlowInstance, generateComponentDisplayName, syncCompositePlacement, recordUserAction, currentProjectName]);
const onConnect = useCallback((connection) => {
if (!activePageId) return;