I can save workflow state + uptated css + started Properties Panek

This commit is contained in:
2025-07-02 23:00:32 +02:00
parent d90613119f
commit 797273e603
7 changed files with 130 additions and 28 deletions

View File

@@ -4,8 +4,8 @@ from fasthtml.xtend import Script
from components.BaseComponent import BaseComponent
from components.workflows.constants import WORKFLOW_DESIGNER_INSTANCE_ID
from components.workflows.db_management import WorkflowsDesignerSettings, WorkflowsDesignerState, WorkflowComponent, \
Connection
from components.workflows.db_management import WorkflowsDesignerSettings, WorkflowComponent, \
Connection, WorkflowsDesignerDbManager
from components_helpers import apply_boundaries, mk_tooltip
from core.utils import get_unique_id
@@ -36,12 +36,15 @@ class WorkflowDesigner(BaseComponent):
def __init__(self, session,
_id=None,
settings_manager=None,
key: str = None,
designer_settings: WorkflowsDesignerSettings = None,
boundaries: dict = None):
super().__init__(session, _id)
self._settings_manager = settings_manager
self._key = key
self._designer_settings = designer_settings
self._state = WorkflowsDesignerState()
self._db = WorkflowsDesignerDbManager(session, settings_manager)
self._state = self._db.load_state(key)
self._boundaries = boundaries
def set_boundaries(self, boundaries: dict):
@@ -66,12 +69,14 @@ class WorkflowDesigner(BaseComponent):
)
self._state.components[component_id] = component
self._db.save_state(self._key, self._state) # update db
return self.refresh()
def move_component(self, component_id, x, y):
if component_id in self._state.components:
self._state.components[component_id].x = int(x)
self._state.components[component_id].y = int(y)
self._db.save_state(self._key, self._state) # update db
return self.refresh()
@@ -83,6 +88,8 @@ class WorkflowDesigner(BaseComponent):
# Remove related connections
self._state.connections = [connection for connection in self._state.connections
if connection.from_id != component_id and connection.to_id != component_id]
# update db
self._db.save_state(self._key, self._state)
return self.refresh()
@@ -95,6 +102,10 @@ class WorkflowDesigner(BaseComponent):
connection_id = f"conn_{len(self._state.connections) + 1}"
connection = Connection(id=connection_id, from_id=from_id, to_id=to_id)
self._state.connections.append(connection)
# update db
self._db.save_state(self._key, self._state)
return self.refresh()
def __ft__(self):
@@ -102,6 +113,7 @@ class WorkflowDesigner(BaseComponent):
H1(f"{self._designer_settings.workflow_name}", cls="text-xl font-bold"),
P("Drag components from the toolbox to the canvas to create your workflow.", cls="text-sm mb-6"),
self._mk_designer(),
self._mk_properties(),
Script(f"bindWorkflowDesigner('{self._id}');"),
**apply_boundaries(self._boundaries),
id=f"{self._id}",
@@ -120,9 +132,9 @@ class WorkflowDesigner(BaseComponent):
return Div(
mk_tooltip(
Div(
Span(info["icon"], cls="text-2xl mb-2"),
H4(info["title"], cls="font-semibold text-sm"),
cls=f"p-3 rounded-lg border-2 {info['color']} text-center"
Span(info["icon"], cls="mb-2"),
H4(info["title"], cls="font-semibold text-xs"),
cls=f"p-2 rounded-lg border-2 {info['color']} flex text-center"
),
tooltip=info["description"]),
cls="wkf-toolbox-item p-2",
@@ -142,9 +154,8 @@ class WorkflowDesigner(BaseComponent):
# Component content
Div(
Span(info["icon"], cls="text-xl mb-1"),
H4(component.title, cls="font-semibold text-sm"),
P(info["description"], cls="text-xs text-gray-600"),
cls=f"p-3 rounded-lg border-2 {info['color']} bg-white shadow-lg"
H4(component.title, cls="font-semibold text-xs"),
cls=f"p-3 rounded-lg border-2 {info['color']} bg-white shadow-lg flex items-center"
),
# Output connection point
@@ -167,9 +178,9 @@ class WorkflowDesigner(BaseComponent):
# Calculate connection points (approximate)
x1 = from_comp.x + 128 # component width + output point
y1 = from_comp.y + 40 # component height / 2
y1 = from_comp.y + 32 # component height / 2
x2 = to_comp.x
y2 = to_comp.y + 40
y2 = to_comp.y + 32
# Create curved path
mid_x = (x1 + x2) / 2
@@ -195,26 +206,25 @@ class WorkflowDesigner(BaseComponent):
# Render components
*[self._mk_workflow_component(comp) for comp in self._state.components.values()],
cls="wkf-canvas bg-white rounded-lg border relative",
cls="wkf-canvas bg-base-100 rounded-lg border relative",
),
def _mk_canvas(self, oob=False):
return Div(
self._mk_elements(),
cls="flex-1 ",
cls="flex-1",
id=f"c_{self._id}",
hx_swap_oob='true' if oob else None,
),
def _mk_toolbox(self):
return Div(
H2("Toolbox", cls="text-lg font-semibold mb-4 text-gray-700"),
Div(
*[self._mk_toolbox_item(comp_type, info)
for comp_type, info in COMPONENT_TYPES.items()],
cls="space-y-3"
cls="space-y-1"
),
cls="w-32 p-4 bg-gray-50 rounded-lg border"
cls="w-32 p-2 bg-base-100 rounded-lg border"
)
def _mk_designer(self):
@@ -224,4 +234,24 @@ class WorkflowDesigner(BaseComponent):
cls="flex gap-4",
id=f"d_{self._id}",
style=f"max-height:{self._state.designer_height}px;"
)
def _mk_properties(self):
return Div(
Div(
H4("Properties"),
Div(
P("Workflow name:", cls="text-sm"),
Div(self._designer_settings.workflow_name, cls="text-base"),
cls="flex flex-col gap-2"
),
),
cls="p-2 bg-base-100 rounded-lg border mt-4",
style=f"max-height:{self._get_properties_height()}px;",
id=f"p_{self._id}",
)
def _get_properties_height(self):
return self._boundaries["height"] - self._state.designer_height