Dialog box at the bottom. Property layout fully operationnel
This commit is contained in:
@@ -59,6 +59,7 @@
|
||||
box-sizing: border-box;
|
||||
font-family: Arial, sans-serif;
|
||||
background-color: var(--color-base-100); /* bg-base-100 */
|
||||
overflow: auto;
|
||||
|
||||
}
|
||||
|
||||
@@ -79,10 +80,10 @@
|
||||
}
|
||||
|
||||
.wkf-properties-properties {
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
position: relative;
|
||||
box-sizing: border-box;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.wkf-properties-handle-left {
|
||||
@@ -105,6 +106,28 @@
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.wkf-properties-top {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
cursor: move;
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
.wkf-properties-handle-top {
|
||||
background-image: radial-gradient(var(--color-splitter) 40%, transparent 0);
|
||||
background-repeat: repeat;
|
||||
background-size: 4px 4px;
|
||||
cursor: move;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 8px;
|
||||
width: 20px;
|
||||
position: relative;
|
||||
top: 1px;
|
||||
}
|
||||
|
||||
.wkf-canvas {
|
||||
position: relative;
|
||||
box-sizing: border-box;
|
||||
|
||||
@@ -11,7 +11,8 @@ from components.workflows.assets.icons import icon_play, icon_pause, icon_stop,
|
||||
from components.workflows.commands import WorkflowDesignerCommandManager
|
||||
from components.workflows.components.WorkflowDesignerProperties import WorkflowDesignerProperties
|
||||
from components.workflows.components.WorkflowPlayer import WorkflowPlayer
|
||||
from components.workflows.constants import WORKFLOW_DESIGNER_INSTANCE_ID, ProcessorTypes
|
||||
from components.workflows.constants import WORKFLOW_DESIGNER_INSTANCE_ID, ProcessorTypes, COMPONENT_TYPES, \
|
||||
PROCESSOR_TYPES
|
||||
from components.workflows.db_management import WorkflowsDesignerSettings, WorkflowComponent, \
|
||||
Connection, WorkflowsDesignerDbManager, ComponentState, WorkflowsDesignerState
|
||||
from components_helpers import apply_boundaries, mk_tooltip, mk_dialog_buttons, mk_icon
|
||||
@@ -23,32 +24,6 @@ from utils.DbManagementHelper import DbManagementHelper
|
||||
|
||||
logger = logging.getLogger("WorkflowDesigner")
|
||||
|
||||
# Component templates
|
||||
COMPONENT_TYPES = {
|
||||
ProcessorTypes.Producer: {
|
||||
"title": "Data Producer",
|
||||
"description": "Generates or loads data",
|
||||
"icon": "📊",
|
||||
"color": "bg-green-100 border-green-300 text-neutral"
|
||||
},
|
||||
ProcessorTypes.Filter: {
|
||||
"title": "Data Filter",
|
||||
"description": "Filters and transforms data",
|
||||
"icon": "🔍",
|
||||
"color": "bg-blue-100 border-blue-300 text-neutral"
|
||||
},
|
||||
ProcessorTypes.Presenter: {
|
||||
"title": "Data Presenter",
|
||||
"description": "Displays or exports data",
|
||||
"icon": "📋",
|
||||
"color": "bg-purple-100 border-purple-300 text-neutral"
|
||||
}
|
||||
}
|
||||
|
||||
PROCESSOR_TYPES = {
|
||||
ProcessorTypes.Producer: ["Repository", "Jira"],
|
||||
ProcessorTypes.Filter: ["Default"],
|
||||
ProcessorTypes.Presenter: ["Default"]}
|
||||
|
||||
|
||||
class WorkflowDesigner(BaseComponent):
|
||||
@@ -216,7 +191,7 @@ class WorkflowDesigner(BaseComponent):
|
||||
undo_redo_attrs = UndoRedoAttrs(f"Select Component {component.title}", on_undo=self.refresh_state)
|
||||
self._db.save_state(self._key, self._state, undo_redo_attrs)
|
||||
|
||||
return self.refresh_properties(), self._undo_redo.refresh()
|
||||
return self.properties.refresh(), self._undo_redo.refresh()
|
||||
|
||||
def save_properties(self, component_id: str, details: dict):
|
||||
if component_id in self._state.components:
|
||||
|
||||
@@ -2,6 +2,9 @@ from fasthtml.common import *
|
||||
from dataclasses import dataclass
|
||||
|
||||
from components.BaseComponent import BaseComponent
|
||||
from components.workflows.constants import COMPONENT_TYPES
|
||||
from components_helpers import mk_dialog_buttons
|
||||
from core.utils import merge_classes
|
||||
|
||||
|
||||
@dataclass
|
||||
@@ -17,12 +20,12 @@ class WorkflowDesignerProperties(BaseComponent):
|
||||
self._owner = owner
|
||||
self._boundaries = self._owner.get_boundaries()
|
||||
self._commands = self._owner.commands
|
||||
self.layout = self.compute_layout()
|
||||
self.layout = None
|
||||
self._component = None
|
||||
self.update_layout()
|
||||
self.update_component(self._owner.get_state().selected_component_id)
|
||||
|
||||
def update_layout(self):
|
||||
self.layout = self.compute_layout()
|
||||
|
||||
def compute_layout(self) -> DesignerLayout:
|
||||
if self._owner.get_state().properties_input_width is None:
|
||||
input_width = self._boundaries["width"] // 3
|
||||
properties_width = self._boundaries["width"] // 3
|
||||
@@ -32,13 +35,19 @@ class WorkflowDesignerProperties(BaseComponent):
|
||||
properties_width = self._owner.get_state().properties_properties_width
|
||||
output_width = self._owner.get_state().properties_output_width
|
||||
|
||||
return DesignerLayout(
|
||||
self.layout = DesignerLayout(
|
||||
input_width=input_width,
|
||||
properties_width=properties_width,
|
||||
output_width=output_width
|
||||
)
|
||||
|
||||
def update_component(self, component_id):
|
||||
if component_id is None or component_id not in self._owner.get_state().components:
|
||||
self._component = None
|
||||
self._component = self._owner.get_state().components[component_id]
|
||||
|
||||
def refresh(self, oob=True):
|
||||
self.update_component(self._owner.get_state().selected_component_id)
|
||||
return self.__ft__(oob=oob)
|
||||
|
||||
def _mk_input(self):
|
||||
@@ -57,30 +66,44 @@ class WorkflowDesignerProperties(BaseComponent):
|
||||
cls="wkf-properties-output"
|
||||
)
|
||||
|
||||
def _mk_header(self, cls=None):
|
||||
if self._component is None:
|
||||
return None
|
||||
|
||||
icon = COMPONENT_TYPES[self._component.type]["icon"]
|
||||
color = COMPONENT_TYPES[self._component.type]["color"]
|
||||
return Div(
|
||||
Div(
|
||||
Span(icon),
|
||||
H4(self._component.title, cls="font-semibold text-xs"),
|
||||
cls=f"rounded-lg border-2 {color} flex text-center px-2"
|
||||
),
|
||||
H1(self._component.id, cls="ml-4"),
|
||||
cls=merge_classes("flex mb-2", cls)
|
||||
)
|
||||
|
||||
def _mk_form(self, cls=None):
|
||||
if self._component is None:
|
||||
return None
|
||||
|
||||
return Div(
|
||||
cls=merge_classes(cls)
|
||||
)
|
||||
|
||||
def _mk_properties(self):
|
||||
return Div(
|
||||
# Drag handle (20px height)
|
||||
Div(
|
||||
"Properties",
|
||||
A(cls="wkf-properties-handle-top"),
|
||||
cls="wkf-properties-top",
|
||||
id=f"ppt_{self._id}",
|
||||
style="height: 20px; background-color: #ddd; cursor: move; text-align: center; line-height: 20px; font-weight: bold; font-size: 12px; border-bottom: 1px solid #bbb;"
|
||||
),
|
||||
|
||||
# Properties content
|
||||
Div(
|
||||
Input(placeholder="output name", style="width: 100%; margin-bottom: 10px;"),
|
||||
Select(
|
||||
Option("Repository", value="repository"),
|
||||
Option("Jira", value="jira"),
|
||||
style="width: 100%; margin-bottom: 10px;"
|
||||
),
|
||||
Div(
|
||||
Button("Save", **self._commands.on_save(), style="margin-right: 5px; padding: 5px 10px;"),
|
||||
Button("Cancel", **self._commands.on_cancel(), style="padding: 5px 10px;"),
|
||||
style="text-align: center;"
|
||||
),
|
||||
style=f"padding: 10px; box-sizing: border-box;"
|
||||
),
|
||||
|
||||
self._mk_header(cls="flex-none"),
|
||||
self._mk_form(cls="flex-1 overflow-y-auto"),
|
||||
mk_dialog_buttons(cls="flex-none mt-auto pb-2"),
|
||||
|
||||
# Left resize handle
|
||||
Div(
|
||||
@@ -95,9 +118,8 @@ class WorkflowDesignerProperties(BaseComponent):
|
||||
),
|
||||
|
||||
id=f"pp_{self._id}",
|
||||
style=f"width: {self.layout.properties_width}px;",
|
||||
cls="wkf-properties-properties"
|
||||
|
||||
style=f"width: {self.layout.properties_width}px; height: 100%;",
|
||||
cls="wkf-properties-properties flex flex-col",
|
||||
)
|
||||
|
||||
def _mk_layout(self):
|
||||
|
||||
@@ -6,11 +6,39 @@ WORKFLOW_DESIGNER_DB_ENTRY = "WorkflowDesigner"
|
||||
WORKFLOW_DESIGNER_DB_SETTINGS_ENTRY = "Settings"
|
||||
WORKFLOW_DESIGNER_DB_STATE_ENTRY = "State"
|
||||
|
||||
|
||||
class ProcessorTypes:
|
||||
Producer = "producer"
|
||||
Filter = "filter"
|
||||
Presenter = "presenter"
|
||||
|
||||
|
||||
COMPONENT_TYPES = {
|
||||
ProcessorTypes.Producer: {
|
||||
"title": "Data Producer",
|
||||
"description": "Generates or loads data",
|
||||
"icon": "📊",
|
||||
"color": "bg-green-100 border-green-300 text-neutral"
|
||||
},
|
||||
ProcessorTypes.Filter: {
|
||||
"title": "Data Filter",
|
||||
"description": "Filters and transforms data",
|
||||
"icon": "🔍",
|
||||
"color": "bg-blue-100 border-blue-300 text-neutral"
|
||||
},
|
||||
ProcessorTypes.Presenter: {
|
||||
"title": "Data Presenter",
|
||||
"description": "Displays or exports data",
|
||||
"icon": "📋",
|
||||
"color": "bg-purple-100 border-purple-300 text-neutral"
|
||||
}
|
||||
}
|
||||
|
||||
PROCESSOR_TYPES = {
|
||||
ProcessorTypes.Producer: ["Repository", "Jira"],
|
||||
ProcessorTypes.Filter: ["Default"],
|
||||
ProcessorTypes.Presenter: ["Default"]}
|
||||
|
||||
ROUTE_ROOT = "/workflows"
|
||||
|
||||
|
||||
@@ -34,4 +62,3 @@ class Routes:
|
||||
PauseWorkflow = "/pause-workflow"
|
||||
StopWorkflow = "/stop-workflow"
|
||||
Refresh = "/refresh"
|
||||
|
||||
Reference in New Issue
Block a user