Fix project reopen persistence
This commit is contained in:
+36
-24
@@ -18,6 +18,13 @@ from werkzeug.security import check_password_hash
|
||||
import database
|
||||
from flask import Response
|
||||
from gds_builder import build_project_gds
|
||||
from layout_files import (
|
||||
LayoutFileError,
|
||||
is_layout_cell_filename,
|
||||
load_layout_cell_files,
|
||||
parse_layout_cell_content,
|
||||
read_layout_cell_file,
|
||||
)
|
||||
from pdk_access import (
|
||||
cleanup_expired_exports,
|
||||
create_export_path,
|
||||
@@ -145,13 +152,17 @@ def cell_routes_path(project_name, cell_name):
|
||||
|
||||
def write_route_points_sidecar(yaml_content, output_path):
|
||||
"""Extract route points from layout YAML and save them beside the cell."""
|
||||
layout = yaml.safe_load(yaml_content) or {}
|
||||
layout = yaml_content if isinstance(yaml_content, dict) else parse_layout_cell_content(yaml_content)
|
||||
routes = {}
|
||||
# The sidecar preserves manually edited route control points separately from
|
||||
# the main YAML file for tooling that wants route-only metadata.
|
||||
for bundle_name, bundle in (layout.get("bundles") or {}).items():
|
||||
if not isinstance(bundle, dict):
|
||||
continue
|
||||
saved_links = []
|
||||
for link in bundle.get("links") or []:
|
||||
if not isinstance(link, dict):
|
||||
continue
|
||||
points = link.get("points") or []
|
||||
if not points:
|
||||
continue
|
||||
@@ -587,22 +598,24 @@ def list_projects():
|
||||
os.makedirs(root, exist_ok=True)
|
||||
|
||||
projects = []
|
||||
# Each project is a folder and each YAML file inside that folder is treated
|
||||
# as one saved cell/canvas.
|
||||
# Each project is a folder and each valid layout YAML file inside that
|
||||
# folder is treated as one saved cell/canvas. Route sidecars and malformed
|
||||
# files are ignored so reopen stays resilient to stale runtime artifacts.
|
||||
for name in sorted(os.listdir(root)):
|
||||
path = os.path.join(root, name)
|
||||
if not os.path.isdir(path):
|
||||
continue
|
||||
cells = []
|
||||
for filename in sorted(os.listdir(path)):
|
||||
if not filename.lower().endswith(('.yml', '.yaml')):
|
||||
if not is_layout_cell_filename(filename):
|
||||
continue
|
||||
cell_name = os.path.splitext(filename)[0]
|
||||
yml_path = os.path.join(path, filename)
|
||||
cells.append({
|
||||
"name": cell_name,
|
||||
"has_layout": os.path.exists(yml_path)
|
||||
})
|
||||
try:
|
||||
read_layout_cell_file(yml_path)
|
||||
except LayoutFileError:
|
||||
continue
|
||||
cells.append({"name": cell_name, "has_layout": True})
|
||||
meta = read_project_meta(name)
|
||||
projects.append({
|
||||
"name": name,
|
||||
@@ -648,24 +661,20 @@ def get_project(project_name):
|
||||
if not os.path.isdir(root):
|
||||
return jsonify({"error": "Project not found"}), 404
|
||||
|
||||
cells = []
|
||||
for filename in sorted(os.listdir(root)):
|
||||
if not filename.lower().endswith(('.yml', '.yaml')):
|
||||
continue
|
||||
cell_name = os.path.splitext(filename)[0]
|
||||
yml_path = os.path.join(root, filename)
|
||||
if not os.path.exists(yml_path):
|
||||
continue
|
||||
with open(yml_path, 'r', encoding='utf-8') as f:
|
||||
cells.append({
|
||||
"name": cell_name,
|
||||
"content": f.read()
|
||||
})
|
||||
loaded_cells, warnings = load_layout_cell_files(root)
|
||||
cells = [
|
||||
{
|
||||
"name": os.path.splitext(cell["filename"])[0],
|
||||
"content": cell["content"]
|
||||
}
|
||||
for cell in loaded_cells
|
||||
]
|
||||
|
||||
return jsonify({
|
||||
"name": safe_name(project_name, 'project_1'),
|
||||
"cells": cells,
|
||||
"technology": read_project_meta(project_name).get("technology")
|
||||
"technology": read_project_meta(project_name).get("technology"),
|
||||
"warnings": warnings
|
||||
})
|
||||
|
||||
|
||||
@@ -728,18 +737,19 @@ def rename_cell(project_name, cell_name):
|
||||
def save_layout():
|
||||
"""Persist a canvas layout YAML document and refresh its preview assets."""
|
||||
try:
|
||||
data = request.get_json()
|
||||
data = request.get_json(silent=True) or {}
|
||||
project = safe_name(data.get('project'), 'project_1')
|
||||
cell = safe_name(data.get('cell'), 'canvas_1')
|
||||
content = data.get('content', '')
|
||||
create_preview = bool(data.get('preview', True))
|
||||
layout_doc = parse_layout_cell_content(content, f"{project}/{cell}.yml")
|
||||
|
||||
save_path = cell_file_path(project, cell)
|
||||
os.makedirs(os.path.dirname(save_path), exist_ok=True)
|
||||
|
||||
with open(save_path, 'w', encoding='utf-8') as f:
|
||||
f.write(content)
|
||||
write_route_points_sidecar(content, cell_routes_path(project, cell))
|
||||
write_route_points_sidecar(layout_doc, cell_routes_path(project, cell))
|
||||
|
||||
svg_path = None
|
||||
svg_version = None
|
||||
@@ -782,6 +792,8 @@ def save_layout():
|
||||
"preview_error": preview_error
|
||||
}), 200
|
||||
|
||||
except LayoutFileError as e:
|
||||
return jsonify({"error": str(e)}), 400
|
||||
except Exception as e:
|
||||
return jsonify({"error": str(e)}), 500
|
||||
|
||||
|
||||
Reference in New Issue
Block a user