Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
90 changes: 89 additions & 1 deletion app/backend/api/routers/project_router.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,12 @@
from pydantic import BaseModel, Field

from app.backend.api.dependencies import getCurrentUser
from app.backend.api.schemas.protocols_schema import ExportProtocolsRequest, RemoteFileWriteRequest
from app.backend.api.schemas.protocols_schema import (
ExportProtocolsRequest,
RemoteFileWriteRequest,
WorkflowExportRequest,
WorkflowImportRequest,
)
from app.backend.api.schemas.tags_schema import ProtocolTagCreateIn, ProtocolTagUpdateIn, ProtocolTagsSetIn
from app.backend.database import getMapper
from app.backend.api.schemas.project_schema import (ProjectCreate, ProjectOut, ProjectUpdate, ProjectShareCreate,
Expand Down Expand Up @@ -1249,6 +1254,89 @@ def exportProtocols(
)


@router.post(
"/{projectId}/protocols/export-workflow",
response_model=Any,
status_code=status.HTTP_200_OK,
)
def exportWorkflowProtocols(
projectId: int,
payload: WorkflowExportRequest,
currentUser=Depends(getCurrentUser),
mapper: PostgresqlFlatMapper = Depends(getMapper),
service: ProjectService = Depends(getProjectService),
):
project = service.getProjectById(
mapper,
projectId,
currentUser,
refresh=False,
checkPid=False,
)
if not project:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Project not found",
)

try:
return service.exportWorkflowProtocolsService(
mapper=mapper,
projectId=projectId,
currentUser=currentUser,
payload=payload,
)
except HTTPException:
raise
except Exception as e:
logger.exception("Error in exportWorkflowProtocols: %s", e)
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=f"Failed to export workflow protocols: {e}",
)


@router.post(
"/{projectId}/protocols/import-workflow",
response_model=Any,
status_code=status.HTTP_200_OK,
)
def importWorkflowProtocols(
projectId: int,
payload: WorkflowImportRequest,
currentUser=Depends(getCurrentUser),
mapper: PostgresqlFlatMapper = Depends(getMapper),
service: ProjectService = Depends(getProjectService),
):
project = service.getProjectById(
mapper,
projectId,
currentUser,
refresh=True,
checkPid=False,
)
if not project:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Project not found",
)

try:
return service.importWorkflowProtocolsService(
mapper=mapper,
projectId=projectId,
currentUser=currentUser,
payload=payload,
)
except HTTPException:
raise
except Exception as e:
logger.exception("Error in importWorkflowProtocols: %s", e)
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=f"Failed to import workflow protocols: {e}",
)

@router.post(
"/{projectId}/protocols/{protocolId}/fs/write",
response_model=Any,
Expand Down
12 changes: 12 additions & 0 deletions app/backend/api/schemas/protocols_schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,3 +87,15 @@ class RemoteFileWriteRequest(BaseModel):
content: str = ""
mimeType: Optional[str] = "application/json"


class WorkflowExportRequest(BaseModel):
protocolIds: List[Union[int, str]] = Field(default_factory=list)
includeUpstream: bool = False


class WorkflowImportRequest(BaseModel):
workflow: Any
mode: str = "append"
sourceProjectId: Optional[Union[int, str]] = None
sourceProjectName: Optional[str] = None

2 changes: 2 additions & 0 deletions app/backend/api/schemas/settings_schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ class UserSettingsOut(BaseModel):
theme: Literal["system", "light", "dark"] = "system"
uiDensity: Literal["comfortable", "compact"] = "comfortable"
fontScale: float = Field(default=1.0, ge=0.85, le=1.25)
workflowViewMode: Optional[Literal["treeTb", "treeLr", "grid", "table"]] = "treeTb"

language: Literal["en", "es"] = "en"
timeZone: str = "Europe/Madrid"
Expand All @@ -56,6 +57,7 @@ class UserSettingsPatch(BaseModel):
theme: Optional[Literal["system", "light", "dark"]] = None
uiDensity: Optional[Literal["comfortable", "compact"]] = None
fontScale: Optional[float] = Field(default=None, ge=0.85, le=1.25)
workflowViewMode: Optional[Literal["treeTb", "treeLr", "grid", "table"]] = None

language: Optional[Literal["en", "es"]] = None
timeZone: Optional[str] = None
Expand Down
Loading
Loading