fix: 优化指引页面复制与流程图布局
This commit is contained in:
@@ -74,14 +74,20 @@
|
||||
|
||||
.df-node-actions {
|
||||
margin-top: 5px;
|
||||
display: flex;
|
||||
gap: 6px;
|
||||
display: flex !important;
|
||||
flex-direction: row !important;
|
||||
flex-wrap: nowrap;
|
||||
align-items: center;
|
||||
gap: 5px;
|
||||
border-top: 1px solid #f3f4f6;
|
||||
padding-top: 5px;
|
||||
}
|
||||
.df-node-actions button,
|
||||
.df-node-actions a {
|
||||
font-size: 10px;
|
||||
display: inline-flex;
|
||||
width: auto !important;
|
||||
font-size: 9px;
|
||||
line-height: 1.2;
|
||||
color: #6b7280;
|
||||
cursor: pointer;
|
||||
background: none;
|
||||
@@ -89,6 +95,7 @@
|
||||
padding: 1px 0;
|
||||
text-decoration: none;
|
||||
transition: color .15s;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.df-node-actions button:hover, .df-node-actions a:hover { color: #3b82f6; }
|
||||
.df-node-actions button.btn-danger:hover { color: #ef4444; }
|
||||
@@ -107,13 +114,15 @@
|
||||
}
|
||||
|
||||
/* Edge label */
|
||||
.drawflow .connection .connection-label {
|
||||
.drawflow .connection-label {
|
||||
font-size: 10px;
|
||||
fill: #1e40af;
|
||||
font-weight: 500;
|
||||
pointer-events: none;
|
||||
dominant-baseline: middle;
|
||||
text-anchor: middle;
|
||||
}
|
||||
.drawflow .connection .connection-label-bg {
|
||||
.drawflow .connection-label-bg {
|
||||
fill: #dbeafe;
|
||||
rx: 3;
|
||||
pointer-events: none;
|
||||
@@ -165,6 +174,7 @@
|
||||
pointer-events: none;
|
||||
line-height: 1.6;
|
||||
}
|
||||
.drawflow .drawflow-node .output[data-label].is-connected::after { content: none; }
|
||||
|
||||
/* ── Dark mode ── */
|
||||
.dark #drawflow {
|
||||
@@ -177,6 +187,8 @@
|
||||
.dark .drawflow .connection .main-path { stroke: #6b7280; }
|
||||
.dark .drawflow .drawflow-node .input,
|
||||
.dark .drawflow .drawflow-node .output { border-color: #6b7280; background: #1f2937; }
|
||||
.dark .drawflow .connection-label { fill: #93c5fd; }
|
||||
.dark .drawflow .connection-label-bg { fill: #1e3a5f; }
|
||||
.dark .drawflow .drawflow-node .output[data-label]::after { color: #93c5fd; background: #1e3a5f; }
|
||||
</style>
|
||||
|
||||
@@ -203,10 +215,72 @@
|
||||
document.body.appendChild(svg);
|
||||
}
|
||||
|
||||
function renderConnectionLabels(edges) {
|
||||
const container = document.getElementById('drawflow');
|
||||
if (!container) return;
|
||||
|
||||
container.querySelectorAll('.connection-label, .connection-label-bg').forEach(el => el.remove());
|
||||
|
||||
const paths = Array.from(container.querySelectorAll('.connection .main-path'));
|
||||
paths.forEach((path, index) => {
|
||||
const label = edges[index]?.label;
|
||||
if (!label) return;
|
||||
|
||||
const svg = path.ownerSVGElement;
|
||||
if (!svg || typeof path.getTotalLength !== 'function') return;
|
||||
|
||||
const point = path.getPointAtLength(path.getTotalLength() / 2);
|
||||
const labelText = String(label);
|
||||
const labelWidth = Math.max(28, labelText.length * 12 + 12);
|
||||
|
||||
const rect = document.createElementNS('http://www.w3.org/2000/svg', 'rect');
|
||||
rect.setAttribute('class', 'connection-label-bg');
|
||||
rect.setAttribute('x', point.x - labelWidth / 2);
|
||||
rect.setAttribute('y', point.y - 10);
|
||||
rect.setAttribute('width', labelWidth);
|
||||
rect.setAttribute('height', 20);
|
||||
|
||||
const text = document.createElementNS('http://www.w3.org/2000/svg', 'text');
|
||||
text.setAttribute('class', 'connection-label');
|
||||
text.setAttribute('x', point.x);
|
||||
text.setAttribute('y', point.y);
|
||||
text.textContent = labelText;
|
||||
|
||||
svg.appendChild(rect);
|
||||
svg.appendChild(text);
|
||||
});
|
||||
}
|
||||
|
||||
function scheduleConnectionLabelsRender(edges = window._dfCurrentEdges ?? []) {
|
||||
cancelAnimationFrame(window._dfLabelFrame);
|
||||
window._dfLabelFrame = requestAnimationFrame(() => renderConnectionLabels(edges));
|
||||
}
|
||||
|
||||
function markConnectedOutputs(edges, pageIdToNodeId) {
|
||||
const container = document.getElementById('drawflow');
|
||||
if (!container) return;
|
||||
|
||||
container.querySelectorAll('.output.is-connected').forEach(el => el.classList.remove('is-connected'));
|
||||
|
||||
edges.forEach(edge => {
|
||||
if (!edge.label) return;
|
||||
|
||||
const fromNodeId = pageIdToNodeId[edge.from];
|
||||
const node = window._dfCurrentNodes?.find(item => item.id === edge.from);
|
||||
const outputIndex = node?.options?.indexOf(edge.label) ?? -1;
|
||||
if (!fromNodeId || outputIndex < 0) return;
|
||||
|
||||
const output = container.querySelector(`#node-${fromNodeId} .output_${outputIndex + 1}`);
|
||||
output?.classList.add('is-connected');
|
||||
});
|
||||
}
|
||||
|
||||
// ── Build / rebuild the Drawflow graph ───────────────────────────────
|
||||
function buildGraph(nodes, edges) {
|
||||
const container = document.getElementById('drawflow');
|
||||
if (!container) return;
|
||||
window._dfCurrentNodes = nodes;
|
||||
window._dfCurrentEdges = edges;
|
||||
|
||||
// 销毁旧实例
|
||||
if (window._dfEditor) {
|
||||
@@ -240,6 +314,7 @@
|
||||
${node.is_entry ? '<div><span class="df-node-badge">入口</span></div>' : ''}
|
||||
<div class="df-node-actions">
|
||||
<button onclick="event.stopPropagation();Livewire.find('${componentId}').mountAction('editPage',{id:${node.id}})">编辑</button>
|
||||
<button onclick="event.stopPropagation();Livewire.find('${componentId}').mountAction('copyPage',{id:${node.id}})">复制</button>
|
||||
<button class="btn-danger" onclick="event.stopPropagation();Livewire.find('${componentId}').mountAction('deletePage',{id:${node.id}})">删除</button>
|
||||
<a href="${escHtml(node.uri)}" target="_blank" rel="noopener" onclick="event.stopPropagation()">预览</a>
|
||||
</div></div>`;
|
||||
@@ -283,6 +358,16 @@
|
||||
try { editor.addConnection(fromNodeId, toNodeId, outputClass, 'input_1'); } catch(e) {}
|
||||
});
|
||||
|
||||
markConnectedOutputs(edges, pageIdToNodeId);
|
||||
|
||||
scheduleConnectionLabelsRender(edges);
|
||||
|
||||
editor.on('nodeMoved', () => scheduleConnectionLabelsRender(edges));
|
||||
editor.on('translate', () => scheduleConnectionLabelsRender(edges));
|
||||
editor.on('zoom', () => scheduleConnectionLabelsRender(edges));
|
||||
container.addEventListener('mouseup', () => scheduleConnectionLabelsRender());
|
||||
container.addEventListener('touchend', () => scheduleConnectionLabelsRender());
|
||||
|
||||
// Drawflow 事件 → Livewire(只在本次 editor 实例上绑定)
|
||||
editor.on('connectionCreated', info => {
|
||||
const from = editor.getNodeFromId(info.output_id);
|
||||
@@ -290,6 +375,7 @@
|
||||
if (from && to) {
|
||||
Livewire.find(componentId).call('addEdge', from.data.pageId, to.data.pageId, info.output_class);
|
||||
}
|
||||
scheduleConnectionLabelsRender(edges);
|
||||
});
|
||||
|
||||
editor.on('connectionRemoved', info => {
|
||||
@@ -298,6 +384,7 @@
|
||||
if (from && to) {
|
||||
Livewire.find(componentId).call('removeEdge', from.data.pageId, to.data.pageId);
|
||||
}
|
||||
scheduleConnectionLabelsRender(edges);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user