import enum import logging from dataclasses import dataclass, field from components.undo_redo.constants import UndoRedoAttrs from components.workflows.constants import WORKFLOWS_DB_ENTRY, WORKFLOW_DESIGNER_DB_ENTRY, \ WORKFLOW_DESIGNER_DB_SETTINGS_ENTRY, WORKFLOW_DESIGNER_DB_STATE_ENTRY from core.settings_management import SettingsManager from core.utils import make_safe_id from utils.ComponentsInstancesHelper import ComponentsInstancesHelper logger = logging.getLogger("WorkflowsSettings") class ComponentState(enum.Enum): """ Represents the execution state of a workflow component. """ SUCCESS = "success" FAILURE = "failure" NOT_RUN = "not_run" # Data structures @dataclass class WorkflowComponent: id: str type: str x: int y: int title: str description: str properties: dict @dataclass class Connection: id: str from_id: str to_id: str @dataclass class WorkflowComponentRuntimeState: """ Represents the runtime state of a single workflow component. """ id: str state: ComponentState = ComponentState.SUCCESS error_message: str | None = None @dataclass class WorkflowsDesignerSettings: workflow_name: str = "No Name" @dataclass class WorkflowsDesignerState: components: dict[str, WorkflowComponent] = field(default_factory=dict) connections: list[Connection] = field(default_factory=list) component_counter: int = 0 designer_height: int = 230 properties_input_width: int = None properties_properties_width : int = None properties_output_width: int = None selected_component_id: str | None = None @dataclass class WorkflowsSettings: workflows: list[str] = field(default_factory=list) selected_workflow: str = None class WorkflowsDbManager: def __init__(self, session: dict, settings_manager: SettingsManager): self.session = session self.settings_manager = settings_manager def add_workflow(self, workflow_name: str): settings = self._get_settings() if not workflow_name: raise ValueError("Workflow name cannot be empty.") if workflow_name in settings.workflows: raise ValueError(f"Workflow '{workflow_name}' already exists.") settings.workflows.append(workflow_name) self.settings_manager.save(self.session, WORKFLOWS_DB_ENTRY, settings) return True def get_workflow(self, workflow_name: str): if not workflow_name: raise ValueError("Workflow name cannot be empty.") settings = self._get_settings() if workflow_name not in settings.workflows: raise ValueError(f"Workflow '{workflow_name}' does not exist.") return next(filter(lambda r: r == workflow_name, settings.workflows)) # def modify_workflow(self, old_workflow_name, new_workflow_name: str, tables: list[str]): # if not old_workflow_name or not new_workflow_name: # raise ValueError("Workflow name cannot be empty.") # # settings = self._get_settings() # for workflow in settings.workflows: # if workflow == old_workflow_name: # workflow.name = new_workflow_name # workflow.tables = tables # # self.settings_manager.save(self.session, workflows_SETTINGS_ENTRY, settings) # return workflow # # else: # raise ValueError(f"workflow '{old_workflow_name}' not found.") def remove_workflow(self, workflow_name): if not workflow_name: raise ValueError("Workflow name cannot be empty.") settings = self._get_settings() if workflow_name not in settings.workflows: raise ValueError(f"workflow '{workflow_name}' does not exist.") settings.workflows.remove(workflow_name) self.settings_manager.save(self.session, WORKFLOWS_DB_ENTRY, settings) return True def exists_workflow(self, workflow_name): if not workflow_name: raise ValueError("workflow name cannot be empty.") settings = self._get_settings() return workflow_name in settings.workflows def get_workflows(self): return self._get_settings().workflows def select_workflow(self, workflow_name: str): """ Select and save the specified workflow name in the current session's settings. :param workflow_name: The name of the workflow to be selected and stored. :type workflow_name: str :return: None """ settings = self._get_settings() settings.selected_workflow = workflow_name self.settings_manager.save(self.session, WORKFLOWS_DB_ENTRY, settings) def get_selected_workflow(self): settings = self._get_settings() return settings.selected_workflow def _get_settings(self): return self.settings_manager.load(self.session, WORKFLOWS_DB_ENTRY, default=WorkflowsSettings()) class WorkflowsDesignerDbManager: def __init__(self, session: dict, settings_manager: SettingsManager): self._session = session self._settings_manager = settings_manager self._undo_redo = ComponentsInstancesHelper.get_undo_redo(session) @staticmethod def _get_db_entry(key): return make_safe_id(f"{WORKFLOW_DESIGNER_DB_ENTRY}_{key}") def save_settings(self, key: str, settings: WorkflowsDesignerSettings): self._settings_manager.put(self._session, self._get_db_entry(key), WORKFLOW_DESIGNER_DB_SETTINGS_ENTRY, settings) def save_state(self, key: str, state: WorkflowsDesignerState, undo_redo_attrs: UndoRedoAttrs = None): db_entry = self._get_db_entry(key) self._settings_manager.put(self._session, db_entry, WORKFLOW_DESIGNER_DB_STATE_ENTRY, state) if undo_redo_attrs is not None: self._undo_redo.snapshot(undo_redo_attrs, db_entry, WORKFLOW_DESIGNER_DB_STATE_ENTRY) def save_all(self, key: str, settings: WorkflowsDesignerSettings = None, state: WorkflowsDesignerState = None): items = {} if settings is not None: items[WORKFLOW_DESIGNER_DB_SETTINGS_ENTRY] = settings if state is not None: items[WORKFLOW_DESIGNER_DB_STATE_ENTRY] = state self._settings_manager.put_many(self._session, self._get_db_entry(key), items) def load_settings(self, key) -> WorkflowsDesignerSettings: return self._settings_manager.get(self._session, self._get_db_entry(key), WORKFLOW_DESIGNER_DB_SETTINGS_ENTRY, default=WorkflowsDesignerSettings()) def load_state(self, key) -> WorkflowsDesignerState: return self._settings_manager.get(self._session, self._get_db_entry(key), WORKFLOW_DESIGNER_DB_STATE_ENTRY, default=WorkflowsDesignerState())