graflow: subflow polishing
This commit is contained in:
@@ -61,8 +61,7 @@
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
}
|
}
|
||||||
.bzgf-node[data-nodetype="refnodein"] .body{ background: #0F0; }
|
.bzgf-node[data-nodetype="refnodein"] .body, .bzgf-node[data-nodetype="refnodeout"] .body{ background: var(--eicui-base-color-grey-25); }
|
||||||
.bzgf-node[data-nodetype="refnodeout"] .body{ background: #FF0; }
|
|
||||||
|
|
||||||
.bzgf-wire{ stroke: var(--eicui-base-color-info); stroke-width: 4px; stroke-dasharray: 10,5; }
|
.bzgf-wire{ stroke: var(--eicui-base-color-info); stroke-width: 4px; stroke-dasharray: 10,5; }
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -96,8 +96,18 @@
|
|||||||
.bzgf-node[data-nodetype="input"] .title,
|
.bzgf-node[data-nodetype="input"] .title,
|
||||||
.bzgf-node[data-nodetype="console"] .title{ background: #555; }
|
.bzgf-node[data-nodetype="console"] .title{ background: #555; }
|
||||||
|
|
||||||
.bzgf-node[data-nodetype="refnodein"] .body, .bzgf-node[data-nodetype="refnodeout"] body{
|
.bzgf-node[data-nodetype="refnodein"], .bzgf-node[data-nodetype="refnodeout"] {
|
||||||
|
width:3em;
|
||||||
|
height:3em;
|
||||||
|
padding: 2px;
|
||||||
|
}
|
||||||
|
.bzgf-node[data-nodetype="refnodein"] .body, .bzgf-node[data-nodetype="refnodeout"] .body{
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
|
width: 3em;
|
||||||
|
height: 3em;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
}
|
}
|
||||||
.bzgf-node[data-nodetype="refnodein"] .body{ background: #0F0; }
|
.bzgf-node[data-nodetype="refnodein"] .body{ background: #0F0; }
|
||||||
.bzgf-node[data-nodetype="refnodeout"] .body{ background: #FF0; }
|
.bzgf-node[data-nodetype="refnodeout"] .body{ background: #FF0; }
|
||||||
@@ -181,11 +191,13 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="bzgf-node" data-nodetype="refnodein">
|
<div class="bzgf-node" data-nodetype="refnodein">
|
||||||
<div class="body">{parentport}</div>
|
<div class="body">{parentport}</div>
|
||||||
|
<div class="port" data-type="out" data-id="out1" data-direction="e"></div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="bzgf-node" data-nodetype="refnodeout">
|
<div class="bzgf-node" data-nodetype="refnodeout">
|
||||||
<div class="body">{parentport}</div>
|
<div class="body">{parentport}</div>
|
||||||
|
<div class="port" data-type="in" data-id="in1" data-direction="w"></div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -58,6 +58,9 @@
|
|||||||
grflw1.addEventListener('subflowLoaded',
|
grflw1.addEventListener('subflowLoaded',
|
||||||
(evt) => { evt.target.querySelector('.demooptions').style.display = 'none'; }
|
(evt) => { evt.target.querySelector('.demooptions').style.display = 'none'; }
|
||||||
)
|
)
|
||||||
|
grflw1.addEventListener('subflowExited',
|
||||||
|
(evt) => { evt.target.querySelector('.demooptions').style.display = 'block'; }
|
||||||
|
)
|
||||||
document.querySelector('[data-trigger="onAutoplace1H"]').addEventListener('click',
|
document.querySelector('[data-trigger="onAutoplace1H"]').addEventListener('click',
|
||||||
(evt) => { grflw1.autoPlace('horizontal', 80, 30, 1000, document.querySelector('[data-id="compunet"]').value) }
|
(evt) => { grflw1.autoPlace('horizontal', 80, 30, 1000, document.querySelector('[data-id="compunet"]').value) }
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -7,7 +7,8 @@
|
|||||||
"coords": { "x": 220, "y": 120}
|
"coords": { "x": 220, "y": 120}
|
||||||
},
|
},
|
||||||
{ "nodeType": "inc",
|
{ "nodeType": "inc",
|
||||||
"subflow": "/app/assets/json/bzGraflow/testFlowEic.json",
|
"subflow": {
|
||||||
|
"url": "/app/assets/json/bzGraflow/testFlowEic.json",
|
||||||
"portLinks": [
|
"portLinks": [
|
||||||
{ "refNodeType": "refnodein", "refnodePort": "out1",
|
{ "refNodeType": "refnodein", "refnodePort": "out1",
|
||||||
"parentPort": "in1",
|
"parentPort": "in1",
|
||||||
@@ -19,7 +20,8 @@
|
|||||||
"subflowNode":"aze5", "subflowPort": "out1",
|
"subflowNode":"aze5", "subflowPort": "out1",
|
||||||
"direction": "out"
|
"direction": "out"
|
||||||
}
|
}
|
||||||
],
|
]
|
||||||
|
},
|
||||||
"id": "aze2",
|
"id": "aze2",
|
||||||
"coords": { "x": 220, "y": 10}
|
"coords": { "x": 220, "y": 10}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -27,7 +27,22 @@
|
|||||||
"title": "Data mapping",
|
"title": "Data mapping",
|
||||||
"subtitle": "Associate content variables with attendees data"
|
"subtitle": "Associate content variables with attendees data"
|
||||||
},
|
},
|
||||||
"data": { "a": "a3", "b":"b3"}
|
"data": { "a": "a3", "b":"b3"},
|
||||||
|
"subflow": {
|
||||||
|
"url": "/app/assets/json/bzGraflow/testFlowICMP.json",
|
||||||
|
"portLinks": [
|
||||||
|
{ "refNodeType": "refnodein", "refnodePort": "out1",
|
||||||
|
"parentPort": "in1",
|
||||||
|
"subflowNode":"cid", "subflowPort": "in3",
|
||||||
|
"direction": "in"
|
||||||
|
},
|
||||||
|
{ "refNodeType": "refnodeout", "refnodePort": "in1",
|
||||||
|
"parentPort": "out1",
|
||||||
|
"subflowNode":"signature", "subflowPort": "out2",
|
||||||
|
"direction": "out"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{ "nodeType": "eicBasic",
|
{ "nodeType": "eicBasic",
|
||||||
"id": "aze4",
|
"id": "aze4",
|
||||||
|
|||||||
Vendored
+23
-9
@@ -202,30 +202,25 @@ class BZgraflow extends Buildoz{
|
|||||||
const parentBB = this.getBoundingClientRect()
|
const parentBB = this.getBoundingClientRect()
|
||||||
|
|
||||||
const flowNode = this.flow?.nodes?.find(n => n.id === id)
|
const flowNode = this.flow?.nodes?.find(n => n.id === id)
|
||||||
const flowUrl = flowNode?.subflow
|
const flowUrl = flowNode.subflow.url
|
||||||
|
|
||||||
const childEl = document.createElement('bz-graflow')
|
const childEl = document.createElement('bz-graflow')
|
||||||
childEl.setAttribute('flow', flowUrl)
|
childEl.setAttribute('flow', flowUrl)
|
||||||
childEl.setAttribute('tension', this.getBZAttribute('tension') || '60')
|
childEl.setAttribute('tension', this.getBZAttribute('tension') || '60')
|
||||||
// Remember which node we "came from" so exitSubflow() can animate back to it.
|
// Remember which node we "came from" so exitSubflow() can animate back to it.
|
||||||
childEl.dataset.enterNodeId = id
|
childEl.dataset.enterNodeId = id
|
||||||
// Match the clicked node's border so the transition feels like we're "expanding" it.
|
|
||||||
const nodeStyle = getComputedStyle(nodeEl)
|
|
||||||
childEl.style.border = nodeStyle.border
|
|
||||||
childEl.style.borderRadius = nodeStyle.borderRadius
|
|
||||||
childEl.style.backgroundColor = nodeStyle.backgroundColor
|
|
||||||
const btnExitSubflow = document.createElement('button')
|
const btnExitSubflow = document.createElement('button')
|
||||||
btnExitSubflow.classList.add('bzgf-zoom-out')
|
btnExitSubflow.classList.add('bzgf-zoom-out')
|
||||||
this.addIcon(btnExitSubflow, 'zoomout')
|
this.addIcon(btnExitSubflow, 'zoomout')
|
||||||
btnExitSubflow.addEventListener('click', () => {
|
btnExitSubflow.addEventListener('click', () => {
|
||||||
this.exitSubflow(childEl)
|
this.exitSubflow(childEl)
|
||||||
})
|
})
|
||||||
childEl.appendChild(btnExitSubflow)
|
|
||||||
// Put the child in the exact same viewport rect as the parent (fixed overlay)
|
// Put the child in the exact same viewport rect as the parent (fixed overlay)
|
||||||
this.invade(this, childEl)
|
this.invade(this, childEl)
|
||||||
|
childEl.hostContainer.appendChild(btnExitSubflow)
|
||||||
|
|
||||||
childEl.addEventListener('flowLoaded', (e) => {
|
childEl.addEventListener('flowLoaded', (e) => {
|
||||||
for(const portLink of flowNode.portLinks){
|
for(const portLink of flowNode.subflow.portLinks){
|
||||||
const nid = crypto.randomUUID()
|
const nid = crypto.randomUUID()
|
||||||
childEl.addNode({
|
childEl.addNode({
|
||||||
"nodeType": portLink.refNodeType,
|
"nodeType": portLink.refNodeType,
|
||||||
@@ -280,6 +275,12 @@ class BZgraflow extends Buildoz{
|
|||||||
childEl.addEventListener('transitionend', (e) => {
|
childEl.addEventListener('transitionend', (e) => {
|
||||||
if(e.propertyName !== 'transform') return
|
if(e.propertyName !== 'transform') return
|
||||||
this.hostContainer.style.visibility = 'hidden'
|
this.hostContainer.style.visibility = 'hidden'
|
||||||
|
// Important for nested subflows:
|
||||||
|
// A non-'none' transform on this element creates a containing block, which would make
|
||||||
|
// any nested `position:fixed` subflow overlay position relative to this element instead
|
||||||
|
// of the viewport (showing up as an extra offset like 8px).
|
||||||
|
childEl.style.transform = 'none'
|
||||||
|
childEl.style.willChange = ''
|
||||||
this.dispatchEvent(new CustomEvent('subflowLoaded', {
|
this.dispatchEvent(new CustomEvent('subflowLoaded', {
|
||||||
detail: { flowUrl },
|
detail: { flowUrl },
|
||||||
bubbles: true,
|
bubbles: true,
|
||||||
@@ -330,7 +331,14 @@ class BZgraflow extends Buildoz{
|
|||||||
this.hostContainer.style.opacity = '0'
|
this.hostContainer.style.opacity = '0'
|
||||||
this.hostContainer.style.transition = `opacity ${durMs}ms ease-in-out`
|
this.hostContainer.style.transition = `opacity ${durMs}ms ease-in-out`
|
||||||
|
|
||||||
// Ensure child animates (it should already have the transform transition set)
|
// Ensure child animates (it may have had transform cleared after enter)
|
||||||
|
childEl.style.transformOrigin = 'top left'
|
||||||
|
childEl.style.willChange = 'transform'
|
||||||
|
childEl.style.transform = 'translate(var(--tx, 0px), var(--ty, 0px)) scale(var(--sx, 1), var(--sy, 1))'
|
||||||
|
childEl.style.setProperty('--tx', '0px')
|
||||||
|
childEl.style.setProperty('--ty', '0px')
|
||||||
|
childEl.style.setProperty('--sx', 1)
|
||||||
|
childEl.style.setProperty('--sy', 1)
|
||||||
childEl.style.transition = `transform ${durMs}ms ease-in-out`
|
childEl.style.transition = `transform ${durMs}ms ease-in-out`
|
||||||
childEl.getBoundingClientRect() // flush
|
childEl.getBoundingClientRect() // flush
|
||||||
|
|
||||||
@@ -350,6 +358,12 @@ class BZgraflow extends Buildoz{
|
|||||||
// Cleanup: ensure parent is fully visible and no longer hidden
|
// Cleanup: ensure parent is fully visible and no longer hidden
|
||||||
this.hostContainer.style.opacity = '1'
|
this.hostContainer.style.opacity = '1'
|
||||||
this.hostContainer.style.visibility = 'visible'
|
this.hostContainer.style.visibility = 'visible'
|
||||||
|
childEl.style.willChange = ''
|
||||||
|
this.dispatchEvent(new CustomEvent('subflowExited', {
|
||||||
|
detail: { },
|
||||||
|
bubbles: true,
|
||||||
|
composed: true,
|
||||||
|
}))
|
||||||
}, { once:true })
|
}, { once:true })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user