fix: persist edge animation mode (None/Snake/Flow) end-to-end
- canvasStore.onConnect: include animated in edge data object (was silently dropped)
- Backend schemas: normalize animated bool/int to string ('none'/'snake'/'flow') via field_validator
- ORM model: change animated column from Boolean to String
- DB migration: convert existing 0/1 boolean rows to 'none'/'snake' strings
This commit is contained in:
@@ -1,9 +1,10 @@
|
||||
from typing import Any
|
||||
|
||||
from pydantic import BaseModel
|
||||
from pydantic import BaseModel, field_validator
|
||||
|
||||
from app.schemas.edges import EdgeResponse
|
||||
from app.schemas.nodes import NodeResponse
|
||||
from app.schemas.utils import normalize_animated
|
||||
|
||||
|
||||
class NodeSave(BaseModel):
|
||||
@@ -44,10 +45,15 @@ class EdgeSave(BaseModel):
|
||||
speed: str | None = None
|
||||
custom_color: str | None = None
|
||||
path_style: str | None = None
|
||||
animated: bool = False
|
||||
animated: str = 'none'
|
||||
source_handle: str | None = None
|
||||
target_handle: str | None = None
|
||||
|
||||
@field_validator('animated', mode='before')
|
||||
@classmethod
|
||||
def validate_animated(cls, v: object) -> str:
|
||||
return normalize_animated(v)
|
||||
|
||||
|
||||
class CanvasSaveRequest(BaseModel):
|
||||
nodes: list[NodeSave] = []
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
from datetime import datetime
|
||||
|
||||
from pydantic import BaseModel
|
||||
from pydantic import BaseModel, field_validator
|
||||
|
||||
from app.schemas.utils import normalize_animated
|
||||
|
||||
|
||||
class EdgeBase(BaseModel):
|
||||
@@ -12,10 +14,15 @@ class EdgeBase(BaseModel):
|
||||
speed: str | None = None
|
||||
custom_color: str | None = None
|
||||
path_style: str | None = None
|
||||
animated: bool = False
|
||||
animated: str = 'none'
|
||||
source_handle: str | None = None
|
||||
target_handle: str | None = None
|
||||
|
||||
@field_validator('animated', mode='before')
|
||||
@classmethod
|
||||
def validate_animated(cls, v: object) -> str:
|
||||
return normalize_animated(v)
|
||||
|
||||
|
||||
class EdgeCreate(EdgeBase):
|
||||
pass
|
||||
@@ -28,10 +35,17 @@ class EdgeUpdate(BaseModel):
|
||||
speed: str | None = None
|
||||
custom_color: str | None = None
|
||||
path_style: str | None = None
|
||||
animated: bool | None = None
|
||||
animated: str | None = None
|
||||
source_handle: str | None = None
|
||||
target_handle: str | None = None
|
||||
|
||||
@field_validator('animated', mode='before')
|
||||
@classmethod
|
||||
def validate_animated(cls, v: object) -> str | None:
|
||||
if v is None:
|
||||
return None
|
||||
return normalize_animated(v)
|
||||
|
||||
|
||||
class EdgeResponse(EdgeBase):
|
||||
id: str
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
def normalize_animated(v: object) -> str:
|
||||
"""Normalize legacy bool/int animated values to string mode ('none'/'snake'/'flow')."""
|
||||
if v is True or v == 1 or v == '1':
|
||||
return 'snake'
|
||||
if v is False or v == 0 or v == '0' or v is None or v == 'none':
|
||||
return 'none'
|
||||
if v in ('snake', 'flow'):
|
||||
return str(v)
|
||||
return 'none'
|
||||
Reference in New Issue
Block a user