feat(editor-ui): add node controls slot to canvas components

Add a new slot 'node-controls' to Canvas components hierarchy (Canvas, WorkflowCanvas, CanvasNode)
to allow custom node controls injection. The slot provides node data and class toggle functionality
to customize node appearance.
This commit is contained in:
Oleg Ivaniv 2024-12-06 14:15:42 +01:00
parent b247103e38
commit a2c2855a1f
No known key found for this signature in database
3 changed files with 35 additions and 3 deletions

View file

@ -663,7 +663,11 @@ provide(CanvasKey, {
@update="onUpdateNodeParameters"
@move="onUpdateNodePosition"
@add="onClickNodeAdd"
/>
>
<template v-if="$slots['node-controls']" #node-controls="canvasNodeProps">
<slot name="node-controls" v-bind="canvasNodeProps" />
</template>
</Node>
</template>
<template #edge-canvas-edge="edgeProps">

View file

@ -74,7 +74,11 @@ onNodesInitialized(() => {
:event-bus="eventBus"
:read-only="readOnly"
v-bind="$attrs"
/>
>
<template v-if="$slots['node-controls']" #node-controls="canvasNodeProps">
<slot name="node-controls" v-bind="canvasNodeProps" />
</template>
</Canvas>
</div>
<slot />
</div>

View file

@ -75,6 +75,7 @@ const isDisabled = computed(() => props.data.disabled);
const nodeTypeDescription = computed(() => {
return nodeTypesStore.getNodeType(props.data.type, props.data.typeVersion);
});
const slotClasses = ref<Record<string, boolean>>({});
const classes = computed(() => ({
[style.canvasNode]: true,
@ -82,6 +83,7 @@ const classes = computed(() => ({
hovered: props.hovered,
selected: props.selected,
'bring-to-front': props.bringToFront,
...slotClasses.value,
}));
/**
@ -232,6 +234,14 @@ function onMove(position: XYPosition) {
emit('move', props.id, position);
}
function toggleSlotClass(className: string) {
if (slotClasses.value[className]) {
delete slotClasses.value[className];
} else {
slotClasses.value[className] = true;
}
}
/**
* Provide
*/
@ -310,8 +320,12 @@ onBeforeUnmount(() => {
/>
</template>
<div v-if="$slots['node-controls']" :class="$style.nodeControls">
<slot name="node-controls" v-bind="{ data, toggleSlotClass }" />
</div>
<CanvasNodeToolbar
v-if="nodeTypeDescription"
v-else-if="nodeTypeDescription"
data-test-id="canvas-node-toolbar"
:read-only="readOnly"
:class="$style.canvasNodeToolbar"
@ -364,4 +378,14 @@ onBeforeUnmount(() => {
opacity: 1;
}
}
.nodeControls {
position: absolute;
bottom: 100%;
z-index: 1;
width: 100%;
margin: auto;
display: flex;
justify-content: center;
}
</style>