Another implementation of undo/redo

This commit is contained in:
2025-07-31 22:54:09 +02:00
parent 72f5f30da6
commit 37c91d0d5d
13 changed files with 228 additions and 94 deletions

View File

@@ -6,8 +6,9 @@ from fasthtml.xtend import Script
from assets.icons import icon_error
from components.BaseComponent import BaseComponent
from components.workflows.assets.icons import icon_play, icon_pause, icon_stop
from components.workflows.commands import WorkflowDesignerCommandManager, AddConnectorCommand
from components.undo_redo.constants import UndoRedoAttrs
from components.workflows.assets.icons import icon_play, icon_pause, icon_stop, icon_refresh
from components.workflows.commands import WorkflowDesignerCommandManager
from components.workflows.components.WorkflowPlayer import WorkflowPlayer
from components.workflows.constants import WORKFLOW_DESIGNER_INSTANCE_ID, ProcessorTypes
from components.workflows.db_management import WorkflowsDesignerSettings, WorkflowComponent, \
@@ -63,6 +64,7 @@ class WorkflowDesigner(BaseComponent):
self._key = key
self._designer_settings = designer_settings
self._db = WorkflowsDesignerDbManager(session, settings_manager)
self._undo_redo = ComponentsInstancesHelper.get_undo_redo(session)
self._state = self._db.load_state(key)
self._boundaries = boundaries
self.commands = WorkflowDesignerCommandManager(self)
@@ -96,6 +98,13 @@ class WorkflowDesigner(BaseComponent):
def refresh_properties(self, oob=False):
return self._mk_properties(oob)
def refresh(self):
return self.__ft__(oob=True)
def refresh_state(self):
self._state = self._db.load_state(self._key)
return self.__ft__(oob=True)
def add_component(self, component_type, x, y):
self._state.component_counter += 1
@@ -111,24 +120,19 @@ class WorkflowDesigner(BaseComponent):
description=info["description"],
properties={"processor_name": PROCESSOR_TYPES[component_type][0]}
)
command = AddConnectorCommand(self, component)
undo_redo = ComponentsInstancesHelper.get_undo_redo(self._session)
#undo_redo.push(command)
self._state.components[component_id] = component
self._db.save_state(self._key, self._state) # update db
undo_redo.snapshot("add_component")
return command.redo(), undo_redo.refresh()
# self._state.components[component_id] = component
# self._db.save_state(self._key, self._state) # update db
# return self.refresh_designer()
undo_redo_attrs = UndoRedoAttrs(f"Add Component '{component_type}'", on_undo=lambda: self.refresh_state())
self._db.save_state(self._key, self._state, undo_redo_attrs) # update db
return self.refresh_designer(), self._undo_redo.refresh()
def move_component(self, component_id, x, y):
if component_id in self._state.components:
self._state.selected_component_id = component_id
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
self._db.save_state(self._key, self._state, ) # update db
return self.refresh_designer(), self.refresh_properties(True)
@@ -247,12 +251,13 @@ class WorkflowDesigner(BaseComponent):
def get_workflow_connections(self):
return self._state.connections
def __ft__(self):
def __ft__(self, oob=False):
return Div(
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"),
Div(
self._mk_media(),
#self._mk_refresh_button(),
self._mk_error_message(),
cls="flex mb-2",
id=f"t_{self._id}"
@@ -263,6 +268,7 @@ class WorkflowDesigner(BaseComponent):
Script(f"bindWorkflowDesigner('{self._id}');"),
**apply_boundaries(self._boundaries),
id=f"{self._id}",
hx_swap_oob='true' if oob else None,
)
def _mk_connection_svg(self, conn: Connection):
@@ -384,6 +390,9 @@ class WorkflowDesigner(BaseComponent):
cls=f"media-controls flex m-2"
)
def _mk_refresh_button(self):
return mk_icon(icon_refresh, **self.commands.refresh())
def _mk_error_message(self):
if not self._error_message:
return Div()