# Module Diagram Editor Design ## Goal Build the function module diagram experience shown in the reference image while preserving the existing EasyCode project-driven diagram flow. The feature has two entry points: - Project diagram center: enhance the existing "功能模块图" tab so it can generate the diagram from the saved project blueprint, then let the user adjust layout and export. - Standalone module diagram editor: provide a SQL2Doc-style editor with a left-side indented structure input and a right-side live module diagram canvas. Both entry points must share the same parsing, graph layout, SVG rendering, and export logic. ## Current Context The frontend already has: - `easycode-web/src/components/AppModuleDiagramView.vue` - `easycode-web/src/utils/appModuleGraph.js` - `easycode-web/src/utils/appModuleExport.js` - `easycode-web/src/views/DiagramCenterView.vue` - tests for `appModuleGraph` and `appModuleExport` The current graph is already close to the target: it renders a root node, two group nodes, vertical leaf nodes, and black right-angle connectors. The new work should evolve this code rather than replace it with a separate diagram implementation. ## User Experience ### Diagram Center In `DiagramCenterView.vue`, the "功能模块图" view should become a richer workspace: - Mode switch: - `自动蓝图`: convert `appBlueprint` into an editable outline and render it. - `缩进结构`: let the user edit the outline directly. - Layout controls: - Density: `标准`, `宽松`, `紧凑` - Direction: `横向`, `竖向` - Font size: a compact select or segmented control for `小`, `标准`, `大`. - Export controls: - SVG export - PNG export - Save behavior: - Save the current outline text, layout options, source mode, and generated graph payload through the existing project diagram save endpoint. The diagram center remains project-aware. It loads the project name and blueprint, and saving writes back to the project diagram list. ### Standalone Editor Add an editor page that can work with or without a project: - With `projectId`: initialize from the project blueprint, allow edits, and save as a project module diagram. - Without `projectId`: act as a pure local tool that renders and exports from the typed outline. The page layout follows the reference: - Header/tool row for density, direction, font size, and export. - Left panel for the indented outline text. - Right panel for the live SVG canvas. - Helpful empty/error states near the editor rather than modal interruptions. Custom undo/redo controls are out of scope for this phase. The textarea keeps the browser's native undo/redo behavior. ## Input Model Use a shared outline model as the internal contract: ```js { title: '学生社团管理系统', groups: [ { title: '管理员端', items: [ { title: '注册登录' }, { title: '用户管理' } ] } ] } ``` ### Indented Text Rules - First non-empty line is the system title. - Second-level lines are groups/modules. - Third-level and deeper lines are leaf functions. - Indentation is counted in spaces. Tabs are normalized to two spaces. - The editor should accept imperfect input: - Blank lines are ignored. - A leaf without a group is placed under a fallback group. - Deeply nested functions are flattened into leaf titles by default. - Parsing should return warnings rather than throwing for recoverable issues. Example: ```text 学生社团管理系统 管理员端 注册登录 用户管理 社团管理 普通用户端 注册登录 社团浏览 社团申请 ``` ### Blueprint Conversion Convert the existing app blueprint into the same outline model: - Root title: project name, then `blueprint.projectName`, then default fallback. - Admin group: `管理员端`, from `adminMenus`. - Frontend group: `普通用户端`, from `frontendMenus`. - Menu title: `menu.name`, then `menu.title`, then `menu.code`. This keeps automatic project generation and manual editing equivalent. ## Graph Layout Keep a deterministic graph object: ```js { title, caption, nodes, edges, groups, canvas, options } ``` Node kinds: - `root` - `group` - `module` Default horizontal layout: - Root centered at the top. - Groups arranged in a row below root. - Leaf functions arranged below each group. - Leaf nodes use vertical writing like the reference image. - Connectors use straight right-angle paths with crisp black strokes. Density controls tune spacing and sizes, not semantic structure: - `compact`: smaller gaps, lower canvas width. - `standard`: current default visual balance. - `relaxed`: wider gaps for export/readability. Vertical layout can be introduced as a second layout strategy: - Root at the left/top. - Groups stacked or arranged vertically. - Leaf modules arranged to the right or below each group. If vertical layout becomes too large, keep horizontal as the production default and make vertical a best-effort option with tests around graph validity. ## Components And Utilities Refactor toward these units: - `appModuleOutline.js` - `parseModuleOutlineText(text)` - `moduleOutlineToText(outline)` - `blueprintToModuleOutline(blueprint, options)` - `normalizeModuleOutline(outline)` - `appModuleGraph.js` - `buildAppModuleGraph(source, options)` - Accept either blueprint or normalized outline. - Keep backward compatibility with current callers. - `appModuleExport.js` - Build standalone SVG from the graph. - Exported SVG must match the visible graph style. - `AppModuleDiagramView.vue` - Pure graph view plus toolbar. - Accept blueprint, outline text, and layout options. - Emit outline/layout changes when used in editor mode. - `ModuleDiagramEditorView.vue` - Standalone page with the two-pane editor. - `DiagramCenterView.vue` - Project-aware host that loads project data, manages save, and embeds the shared component. ## Data Flow Diagram center automatic mode: ```text project.appBlueprint + project.projectName -> blueprintToModuleOutline -> moduleOutlineToText -> parseModuleOutlineText -> buildAppModuleGraph -> AppModuleDiagramView -> export/save ``` Standalone editor: ```text outline textarea -> parseModuleOutlineText -> buildAppModuleGraph -> AppModuleDiagramView -> export/save if projectId exists ``` ## Error Handling - Empty input shows an empty state instead of rendering a broken graph. - Invalid indentation shows non-blocking warnings. - Export failures use `ElMessage.warning`. - Save failures use the existing `ElMessage.error` pattern in `DiagramCenterView.vue`. - Long labels are truncated in horizontal boxes and clipped/ellipsized in vertical leaf boxes. ## Testing Add focused frontend tests before implementation: - `parseModuleOutlineText` parses the reference student club outline. - Tabs normalize to two spaces. - Missing root or empty input returns an empty outline with warnings. - `blueprintToModuleOutline` maps `adminMenus` to `管理员端` and `frontendMenus` to `普通用户端`. - `buildAppModuleGraph` supports a normalized outline source. - Density options change canvas or spacing predictably. - Export SVG contains the expected text, rectangles, and paths without `foreignObject`. Use existing Node test style in `easycode-web/src/utils/*.test.mjs`. ## Non-Goals - No drag-and-drop node editing in this phase. - No AI generation changes in this phase. - No backend schema change. Store source mode, outline text, layout options, and graph data inside the existing `diagramJson` payload. - No pixel-perfect clone of SQL2Doc branding; the goal is the same module diagram workflow and thesis-style output inside EasyCode. ## Acceptance Criteria - Users can open the project diagram center and view a module diagram generated from the project blueprint. - Users can switch to indented text mode, edit the structure, and see the diagram update. - Users can open the standalone module diagram editor and build the same style of diagram from text. - The generated diagram visually matches the reference style: white canvas, black outlined boxes, straight black connectors, vertical leaf labels. - SVG and PNG exports reflect the current layout settings. - Saving a project module diagram preserves source mode, outline text, layout options, and graph data. - Existing module diagram tests continue to pass, and new parser/layout/export tests pass.