graflow: EIC + text replacement

This commit is contained in:
STEINNI
2026-01-07 10:28:23 +00:00
parent 797d86d4d9
commit 53dd4b1458
5 changed files with 171 additions and 29 deletions
+59
View File
@@ -0,0 +1,59 @@
<style>
.bzgf-node {
width: 160px;
height: 80px;
color: black;
text-align: center;
position: absolute;
padding: .5em;
}
.bzgf-node .body{
z-index: 1;
position: absolute;
inset: 0;
background: var(--eicui-base-color-grey-25);
border:2px solid var(--eicui-base-color-grey-50);
border-radius: 6px;
}
.bzgf-node .title {
font-family: Arial, Helvetica, sans-serif;
font-weight: bold;
color: var(--app-color-black);
margin: .5em auto .2em auto;
}
.bzgf-node .subtitle {
font-family: Arial, Helvetica, sans-serif;
font-size: .9em;
color: var(--eicui-base-color-primary-100);
width: 90%;
margin: auto;
}
.bzgf-node .port{
position: absolute;
height: 10px;
width: 10px;
background: var(--eicui-base-color-grey-20);
border-radius: 10px;
}
.bzgf-node [data-direction="w"]{ left: -4px; top: 50%; transform: translateY(-50%);}
.bzgf-node [data-direction="e"]{ right: -4px; top: 50%; transform: translateY(-50%);}
.bzgf-node [data-direction="n"]{ top: -4px; left: 50%; transform: translateX(-50%);}
.bzgf-node [data-direction="s"]{ bottom: -4px; left: 50%; transform: translateX(-50%);}
.bzgf-wire{ stroke: var(--eicui-base-color-info); stroke-width: 4px; stroke-dasharray: 10,5; }
</style>
<template>
<div class="bzgf-node" data-nodetype="eicBasic">
<div class="body">
<div class="title">{title}</div>
<div class="subtitle">{subtitle}</div>
</div>
<div class="port" data-type="in" data-id="in1" data-direction="w"></div>
<div class="port" data-type="out" data-id="out1" data-direction="e"></div>
</div>
</template>
+8 -6
View File
@@ -14,7 +14,8 @@
.bzgf-node .text {
position: absolute;
top: 50%;
transform: translateY(-50%);
left: 50%;
transform: translateX(-50%) translateY(-50%);
width: 100%;
height: 2em;
color: white;
@@ -42,6 +43,8 @@
height: 30px;
border-radius: 50%;
}
.bzgf-node[data-nodetype="start"] .text,
.bzgf-node[data-nodetype="end"] .text{ width: 80%; }
.bzgf-node[data-nodetype="condition"]{
border: none;
@@ -66,9 +69,10 @@
height: 70px;
padding: 0;
}
.bzgf-node[data-nodetype="process"] .text{ width: 80%; }
.bzgf-node[data-nodetype="process"] .dbline{
border: 1px solid white;
width: 80%;
width: 75%;
height: 100%;
position: absolute;
top: -1px;
@@ -94,11 +98,8 @@
}
.bzgf-node[data-nodetype="database"] .text{
background: black;
width: 99%;
height: 98%;
width: 87%;
z-index: 1;
position: absolute;
inset: 0;
}
.bzgf-node[data-nodetype="database"] .bottom{
z-index: 0;
@@ -120,6 +121,7 @@
padding: 0;
border: none;
}
.bzgf-node[data-nodetype="preparation"] .text{ width: 85%; }
.bzgf-node[data-nodetype="preparation"] .outerframe{
width: 100%;
height: 100%;
+52 -19
View File
@@ -4,24 +4,38 @@
<title>graflow</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<link type="text/css" rel="stylesheet" href="https://threejs.org/examples/main.css">
<link type="text/css" rel="stylesheet" href="/app/thirdparty/eicui/eicui-2.0.css">
<link type="text/css" rel="stylesheet" href="../../thirdparty/buildoz/buildoz.css">
<script src="../../thirdparty/buildoz/buildoz.js"></script>
<script src="../../thirdparty/buildoz/bzGraflow.js"></script>
<style>
bz-graflow.compunet{
overflow: scroll;
border: 5px ridge #4BABFF;
width: 80vw;
height: 40vh;
body{
display: grid;
grid-gap: 5px;
background:#888;
}
bz-graflow.organi{
overflow: scroll;
border: 5px ridge #4BABFF;
width: 40vw;
height: 100vh;
.demooptions{
padding: 2px;
position: absolute;
top: 2px;
left: 2px;
width: 10em;
background: #CCC8;
border-radius: 5px;
text-align: center;
}
.demooptions button{
text-transform: none;
font-size: .8em;
margin: 2px;
}
bz-graflow{
overflow: scroll;
border: 2px dotted #4BABFF;
}
bz-graflow.compunet{ grid-column: 1 / -1; width: 80vw; height: 40vh; background:black; }
bz-graflow.eic{ grid-column: 1 / -1; width: 80vw; height: 40vh; background: var(--eicui-base-color-grey-10); }
bz-graflow.organi{ width: 40vw; height: 100vh; background:black; }
</style>
<script>
window.addEventListener('load',()=>{
@@ -40,17 +54,36 @@
document.querySelector('[data-trigger="onAutoplace2V"]').addEventListener('click',
(evt) => { grflw2.autoPlace('vertical') }
)
const grflw3 = document.querySelector('bz-graflow.organi')
document.querySelector('[data-trigger="onAutoplace3H"]').addEventListener('click',
(evt) => { grflw3.autoPlace('horizontal') }
)
document.querySelector('[data-trigger="onAutoplace3V"]').addEventListener('click',
(evt) => { grflw3.autoPlace('vertical') }
)
})
</script>
</head>
<body>
<bz-graflow class="compunet" flow="/app/assets/json/bzGraflow/testFlow1.json" tension="60"></bz-graflow>
<button data-trigger="onAutoplace1H" style="margin:10px;">auto-place Horizontal</button>
<button data-trigger="onAutoplace1V" style="margin:10px;">auto-place Vertical</button>
<bz-graflow class="organi" flow="/app/assets/json/bzGraflow/testFlow2.json" tension="60"></bz-graflow>
<button data-trigger="onAutoplace2H" style="margin:10px;">auto-place Horizontal</button>
<button data-trigger="onAutoplace2V" style="margin:10px;">auto-place Vertical</button>
<bz-graflow class="compunet" flow="/app/assets/json/bzGraflow/testFlow1.json" tension="60">
<div class="demooptions">
<button data-trigger="onAutoplace1H">Auto-place Horizontal</button>
<button data-trigger="onAutoplace1V">Auto-place Vertical</button>
</div>
</bz-graflow>
<bz-graflow class="eic" flow="/app/assets/json/bzGraflow/testFlowEic.json" tension="60">
<div class="demooptions">
<button data-trigger="onAutoplace2H">Auto-place Horizontal</button>
<button data-trigger="onAutoplace2V">Auto-place Vertical</button>
</div>
</bz-graflow>
<bz-graflow class="organi" flow="/app/assets/json/bzGraflow/testFlow2.json" tension="60">
<div class="demooptions">
<button data-trigger="onAutoplace3H">Auto-place Horizontal</button>
<button data-trigger="onAutoplace3V">Auto-place Vertical</button>
</div>
</bz-graflow>
</body>
</html>
@@ -0,0 +1,35 @@
{
"nodesFile": "/app/assets/html/bzGraflow/nodesEIC.html",
"flow": {
"nodes":[
{ "nodeType": "eicBasic",
"id": "aze",
"coords": { "x": 50, "y": 120},
"data": {
"title": "Build attendees list",
"subtitle": "Build an attendees list to email"
}
},
{ "nodeType": "eicBasic",
"id": "aze2",
"coords": { "x": 300, "y": 120},
"data": {
"title": "Select message",
"subtitle": "Select an email template"
}
},
{ "nodeType": "eicBasic",
"id": "aze3",
"coords": { "x": 550, "y": 120},
"data": {
"title": "Data mapping",
"subtitle": "Associate content variables with attendees data"
}
}
],
"links": [
{ "from": ["aze", "out1"], "to": ["aze2", "in1"] },
{ "from": ["aze2", "out1"], "to": ["aze3", "in1"] }
]
}
}
+17 -4
View File
@@ -30,6 +30,12 @@ class BZgraflow extends Buildoz{
this.loadFlow(flowUrl) // Let it load async
}
error(msg, err){
this.innerHTML = `<div style="background:red;color:black;margin: auto;width: fit-content;">${msg}</div>`
if(err) console.error(msg, err)
else console.error(msg)
}
async loadFlow(url){
const res = await fetch(url+'?'+crypto.randomUUID())
const buf = await res.text()
@@ -37,11 +43,12 @@ class BZgraflow extends Buildoz{
try{
flowObj = JSON.parse(buf)
} catch(err){
console.error('Could not parse flow JSON!?', err)
this.error('Could not parse flow JSON!?', err)
return
}
if(!flowObj.nodesFile){
console.error('No nodesFile in JSON!?')
this.error('No nodesFile in JSON!?')
return
}
await this.loadNodes(flowObj.nodesFile)
@@ -81,9 +88,15 @@ class BZgraflow extends Buildoz{
}
}
addNode(type, id, x, y){
addNode(type, id, x, y, data){
if(!(type in this.nodesRegistry)){ console.warn(`Unknown node type (${type})`); return(null)}
const nodeDef = this.nodesRegistry[type]
this.stagedNodes[id] = nodeDef.cloneNode(true)
if(data){
for(const token in data){
this.stagedNodes[id].innerHTML = this.stagedNodes[id].innerHTML.replace(new RegExp(`\{${token}\}`, 'g'), data[token])
}
}
const portEls = this.stagedNodes[id].querySelectorAll('.port')
this.stagedNodes[id].style.left = `${x}px`
this.stagedNodes[id].style.top = `${y}px`
@@ -113,7 +126,7 @@ class BZgraflow extends Buildoz{
let x = 0
let y = 0
for(const node of this.flow.nodes){
const nodeEl = this.addNode(node.nodeType, node.id , node.coords.x, node.coords.y)
const nodeEl = this.addNode(node.nodeType, node.id , node.coords.x, node.coords.y, node.data)
}
for(const link of this.flow.links){
this.addWire(link)