fixed chicked&egg&connectedCB issue between graflow & editor + fixed no Flow issue in graflow + Fixed nodesMove issue on displaced graflow + graflowEditor: DND ok
This commit is contained in:
@@ -60,7 +60,8 @@ class Buildoz extends HTMLElement {
|
||||
fireEvent(eventName, detail){
|
||||
let myname = this.tagName.toLocaleLowerCase()
|
||||
myname = myname.substring(myname.indexOf('-')+1)
|
||||
this.dispatchEvent(new CustomEvent(`bz:${myname}:${eventName}`, {
|
||||
const eventFullName = `bz:${myname}:${eventName}`
|
||||
this.dispatchEvent(new CustomEvent(eventFullName, {
|
||||
detail,
|
||||
bubbles: true,
|
||||
composed: true,
|
||||
|
||||
@@ -16,7 +16,8 @@ class BZgrafloweditor extends Buildoz{
|
||||
this.defaultAttrs = { }
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
async connectedCallback() {
|
||||
await customElements.whenDefined('bz-graflow')
|
||||
super.connectedCallback()
|
||||
const nodesUrl = this.getBZAttribute('nodes')
|
||||
this.mainContainer = document.createElement('div')
|
||||
@@ -26,20 +27,64 @@ class BZgrafloweditor extends Buildoz{
|
||||
this.mainContainer.append(this.nodesContainer)
|
||||
this.graflow = document.createElement('bz-graflow')
|
||||
this.graflow.setAttribute('nodes', nodesUrl)
|
||||
this.graflow.setAttribute('edit', "nodesmove,editwires,dropnodes")
|
||||
this.graflow.addEventListener('bz:graflow:domConnected', this.setupDropZone.bind(this))
|
||||
this.mainContainer.append(this.graflow)
|
||||
this.append(this.mainContainer)
|
||||
|
||||
this.graflow.addEventListener('bz:graflow:nodesLoaded', this.refreshNodes.bind(this))
|
||||
this.graflow.loadNodes(nodesUrl)
|
||||
|
||||
}
|
||||
|
||||
refreshNodes(e){
|
||||
for(const nodeType in this.graflow.nodesRegistry){
|
||||
const nodeDef = this.graflow.nodesRegistry[nodeType]
|
||||
this.nodesContainer.append(nodeDef.cloneNode(true))
|
||||
if(nodeDef.dataset.editor=='exclude') continue
|
||||
const node = nodeDef.cloneNode(true)
|
||||
this.makeNodeDraggable(node)
|
||||
this.nodesContainer.append(node)
|
||||
}
|
||||
}
|
||||
|
||||
makeNodeDraggable(node){
|
||||
node.draggable = true
|
||||
node.style.cursor = 'pointer'
|
||||
node.addEventListener('dragstart', (evt) => {
|
||||
evt.dataTransfer.setData('text/plain', node.dataset.nodetype)
|
||||
evt.dataTransfer.effectAllowed = 'copy'
|
||||
evt.dataTransfer.setDragImage(node, evt.offsetX, evt.offsetY)
|
||||
})
|
||||
}
|
||||
|
||||
onNodeDragEnd(evt){
|
||||
console.log('drag end', evt)
|
||||
evt.dataTransfer.clearData()
|
||||
}
|
||||
|
||||
setupDropZone(){
|
||||
const dropZone = this.graflow.wiresContainer
|
||||
const nodesContainer = this.graflow.nodesContainer
|
||||
dropZone.addEventListener('dragover', (evt) => {
|
||||
evt.preventDefault()
|
||||
evt.dataTransfer.dropEffect = 'copy'
|
||||
})
|
||||
dropZone.addEventListener('drop', (evt) => {
|
||||
evt.preventDefault()
|
||||
const nodeType = evt.dataTransfer.getData('text/plain')
|
||||
if(!nodeType || !(nodeType in this.graflow.nodesRegistry)) return
|
||||
const rect = nodesContainer.getBoundingClientRect()
|
||||
const x = evt.clientX - rect.left + nodesContainer.scrollLeft
|
||||
const y = evt.clientY - rect.top + nodesContainer.scrollTop
|
||||
const id = 'n' + crypto.randomUUID().replace(/-/g, '').slice(0, 8)
|
||||
this.graflow.addNode({ id, nodeType, coords: { x, y } })
|
||||
for(const node of this.graflow.flow.nodes){
|
||||
if(node.id == id){
|
||||
node.coords.x = x
|
||||
node.coords.y = y
|
||||
break
|
||||
}
|
||||
}
|
||||
this.graflow.refresh()
|
||||
})
|
||||
}
|
||||
}
|
||||
Buildoz.define('grafloweditor', BZgrafloweditor)
|
||||
40
bzGraflow.js
40
bzGraflow.js
@@ -66,10 +66,6 @@ class BZgraflow extends Buildoz{
|
||||
|
||||
connectedCallback() {
|
||||
super.connectedCallback()
|
||||
const flowUrl = this.getBZAttribute('flow')
|
||||
if(!flowUrl) return // Be tolerant: maybe injected later from JS above
|
||||
// If attribute "isolated" is present, render inside a shadow root.
|
||||
// Otherwise, render in light DOM (no shadow DOM).
|
||||
this.hostContainer = document.createElement('div')
|
||||
this.hostContainer.classList.add('bzgf-main-container')
|
||||
this.mainContainer = this.hasAttribute('isolated')
|
||||
@@ -96,7 +92,10 @@ class BZgraflow extends Buildoz{
|
||||
this.NodesReceiver = new DroppingNodes(this, '.bzgf-node')
|
||||
}
|
||||
}
|
||||
this.loadFlow(flowUrl)
|
||||
this.fireEvent('domConnected', { graflow: this })
|
||||
const flowUrl = this.getBZAttribute('flow')
|
||||
if(flowUrl) this.loadFlow(flowUrl)
|
||||
else this.initFlow()
|
||||
}
|
||||
|
||||
error(msg, err){
|
||||
@@ -126,6 +125,10 @@ class BZgraflow extends Buildoz{
|
||||
this.fireEvent('flowLoaded', { url: url })
|
||||
}
|
||||
|
||||
initFlow(){
|
||||
this.flow = { nodes: [], links: [] }
|
||||
}
|
||||
|
||||
async loadNodes(url) {
|
||||
const res = await fetch(url+'?'+crypto.randomUUID())
|
||||
const html = await res.text()
|
||||
@@ -1217,17 +1220,17 @@ class MovingNodes{
|
||||
if(e.target != handle) return
|
||||
}
|
||||
|
||||
|
||||
|
||||
const rect = node.getBoundingClientRect()
|
||||
|
||||
const parentBB = this.nodesContainer.getBoundingClientRect()
|
||||
const offsetX = rect.left - parentBB.left + this.nodesContainer.scrollLeft
|
||||
const offsetY = rect.top - parentBB.top + this.nodesContainer.scrollTop
|
||||
this.state = {
|
||||
node,
|
||||
handle,
|
||||
startX: e.clientX,
|
||||
startY: e.clientY,
|
||||
offsetX: rect.left,
|
||||
offsetY: rect.top
|
||||
offsetX,
|
||||
offsetY
|
||||
}
|
||||
const x = e.clientX - this.state.startX + this.state.offsetX
|
||||
const y = e.clientY - this.state.startY + this.state.offsetY
|
||||
@@ -1252,11 +1255,20 @@ class MovingNodes{
|
||||
|
||||
pointerUp(e){
|
||||
if(!this.state) return
|
||||
this.state.node.releasePointerCapture(e.pointerId)
|
||||
this.state.node.style.pointerEvents = ''
|
||||
const { node, startX, startY, offsetX, offsetY } = this.state
|
||||
const x = e.clientX - startX + offsetX
|
||||
const y = e.clientY - startY + offsetY
|
||||
node.releasePointerCapture(e.pointerId)
|
||||
node.style.pointerEvents = ''
|
||||
for(const n of this.graflow.flow.nodes){
|
||||
if(n.id == node.dataset.id){
|
||||
n.coords.x = x
|
||||
n.coords.y = y
|
||||
break
|
||||
}
|
||||
}
|
||||
this.graflow.fireEvent('nodeMoved', { nodeId: node.dataset.id, x, y })
|
||||
this.state = null
|
||||
|
||||
this.graflow.fireEvent('nodeMoved', { nodeId: this.state.node.dataset.id, x: this.state.x, y: this.state.y })
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -110,6 +110,7 @@
|
||||
width:3em;
|
||||
height:3em;
|
||||
padding: 2px;
|
||||
border: none;
|
||||
}
|
||||
.bzgf-node[data-nodetype="refnodein"] .body, .bzgf-node[data-nodetype="refnodeout"] .body{
|
||||
border-radius: 50%;
|
||||
@@ -118,6 +119,10 @@
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin:0;
|
||||
}
|
||||
.bzgf-node[data-nodetype="refnodein"] .port, .bzgf-node[data-nodetype="refnodeout"] .port{
|
||||
top: 50%;
|
||||
}
|
||||
.bzgf-node[data-nodetype="refnodein"] .body{ background: #0F0; }
|
||||
.bzgf-node[data-nodetype="refnodeout"] .body{ background: #FF0; }
|
||||
@@ -209,16 +214,15 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
<template>
|
||||
<div class="bzgf-node" data-nodetype="refnodein">
|
||||
<div class="bzgf-node" data-nodetype="refnodein" data-editor="exclude">
|
||||
<div class="body">{parentport}</div>
|
||||
<div class="port" data-type="out" data-id="out1" data-direction="e"></div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template>
|
||||
<div class="bzgf-node" data-nodetype="refnodeout">
|
||||
<div class="bzgf-node" data-nodetype="refnodeout" data-editor="exclude">
|
||||
<div class="body">{parentport}</div>
|
||||
<div class="port" data-type="in" data-id="in1" data-direction="w"></div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user