fix(ui): scope spatial tools to scene

This commit is contained in:
DCCONSTRUCTIONS
2026-07-18 11:31:44 +03:00
parent 574a494759
commit 0ac6424c46
9 changed files with 216 additions and 142 deletions
+50 -7
View File
@@ -118,7 +118,7 @@ class SceneSettingsDocument(StrictApiModel):
show_camera_frustums: bool
class ToolWindowsDocument(StrictApiModel):
class LegacyToolWindowsDocument(StrictApiModel):
sources_open: bool
display_open: bool
layers_open: bool
@@ -151,12 +151,23 @@ class ViewportSize(StrictApiModel):
height: float = Field(gt=0.0, le=100_000.0)
class LayoutPutRequest(StrictApiModel):
class LegacyLayoutV1Document(StrictApiModel):
version: Literal[1]
revision: int = Field(ge=0, le=MAX_SAFE_INTEGER)
workspace_id: Literal["observation.spatial"]
scene_settings: SceneSettingsDocument
tool_windows: ToolWindowsDocument
tool_windows: LegacyToolWindowsDocument
visible_source_ids: list[str]
active_floating_source_id: str | None
window_rects: dict[str, NormalizedWindowRect]
viewport_size: ViewportSize
class LayoutPutRequest(StrictApiModel):
version: Literal[2]
revision: int = Field(ge=0, le=MAX_SAFE_INTEGER)
workspace_id: Literal["observation.spatial"]
scene_settings: SceneSettingsDocument
visible_source_ids: list[str]
active_floating_source_id: str | None
window_rects: dict[str, NormalizedWindowRect]
@@ -791,7 +802,12 @@ def build_session_router(
def get_workspace_layout(workspace_id: str, response: Response) -> dict[str, Any]:
try:
stored = store.get_layout(workspace_id)
document = _layout_document(stored.workspace_id, stored.revision, stored.layout)
document = _layout_document(
stored.workspace_id,
stored.schema_version,
stored.revision,
stored.layout,
)
response.headers["ETag"] = f'"{stored.revision}"'
return document
except SessionNotFoundError as exc:
@@ -824,7 +840,12 @@ def build_session_router(
layout=payload,
)
response.headers["ETag"] = f'"{stored.revision}"'
return _layout_document(stored.workspace_id, stored.revision, stored.layout)
return _layout_document(
stored.workspace_id,
stored.schema_version,
stored.revision,
stored.layout,
)
except LayoutConflictError as exc:
raise HTTPException(status_code=412, detail=str(exc)) from exc
except ValueError as exc:
@@ -885,20 +906,42 @@ def _parse_if_match(value: str) -> int:
def _layout_document(
workspace_id: str,
schema_version: int,
revision: int,
layout: dict[str, Any],
) -> dict[str, Any]:
if schema_version == 1:
try:
legacy = LegacyLayoutV1Document.model_validate(
{
"version": 1,
"revision": revision,
"workspace_id": workspace_id,
**layout,
}
)
except ValueError as exc:
raise SessionIntegrityError(
"stored workspace layout violates schema version 1"
) from exc
layout = legacy.model_dump(
mode="json",
exclude={"version", "revision", "workspace_id", "tool_windows"},
)
schema_version = 2
if schema_version != 2:
raise SessionIntegrityError("stored workspace layout schema is unsupported")
try:
document = LayoutPutRequest.model_validate(
{
"version": 1,
"version": 2,
"revision": revision,
"workspace_id": workspace_id,
**layout,
}
)
except ValueError as exc:
raise SessionIntegrityError("stored workspace layout violates schema version 1") from exc
raise SessionIntegrityError("stored workspace layout violates schema version 2") from exc
return document.model_dump(mode="json")