# RobotNet10.MapEditor Map Editor UI component library for RobotNet10 system. ## 📁 Project Structure ``` RobotNet10.MapEditor/ ├── Pages/ │ └── LayoutManager.razor ⭐ Main page │ ├── Components/ │ ├── LayoutManager/ │ │ ├── LayoutTreePanel.razor ⭐ Tree hierarchy (Left panel) │ │ ├── LayoutPreviewPanel.razor ⭐ Preview + Actions (Right panel) │ │ └── Dialogs/ │ │ ├── CreateLayoutDialog.razor │ │ ├── CreateVersionDialog.razor │ │ ├── CreateLevelDialog.razor │ │ ├── ImportLayoutDialog.razor │ │ └── ExportLayoutDialog.razor │ │ │ └── Shared/ │ └── SvgPreviewCanvas.razor ⭐ SVG mini preview │ ├── Services/ │ ├── API/ │ │ └── MapManagerApiService.cs ⭐ HTTP client wrapper │ │ │ └── State/ │ └── LayoutManagerState.cs ⭐ State management │ ├── Models/ │ └── TreeItemModel.cs ⭐ Tree node model │ ├── _Imports.razor ⭐ Global imports └── RobotNet10.MapEditor.csproj ``` ## 🎯 Features ### LayoutManager Page **Left Panel - Layout Tree:** - ✅ Hierarchical view: Layout → Version → Level - ✅ Context menu for each item - ✅ Create/Delete operations - ✅ Activate/Deactivate layouts - ✅ Search functionality **Right Panel - Preview:** - ✅ SVG-based mini preview - ✅ Shows background image, nodes, edges, stations - ✅ Layout information display - ✅ Editor settings (expandable) - ✅ Edit and Export buttons **Dialogs:** - ✅ Create Layout (LayoutId, LayoutName, Description) - ✅ Create Version (Version number, Description) - ✅ Create Level (LevelId, Order, Editor settings) - ✅ Import LIF (Upload JSON - placeholder) - ✅ Export LIF (Download JSON - placeholder) ## 🔧 Dependencies **NuGet Packages:** - `Microsoft.AspNetCore.Components.Web` (10.0.0) - `Microsoft.Extensions.Http` (10.0.0) **Project References:** - `RobotNet10.Components` (for MudBlazor) - `RobotNet10.MapEditor.Shared` (for DTOs) ## 🚀 Usage ### 1. Register Services In your Blazor application's `Program.cs`: ```csharp using RobotNet10.MapEditor.Services.API; using RobotNet10.MapEditor.Services.State; var builder = WebApplication.CreateBuilder(args); // Add HttpClient for MapManager API builder.Services.AddHttpClient(); // Add State Management builder.Services.AddScoped(); // Add MudBlazor (if not already added) builder.Services.AddMudServices(); var app = builder.Build(); ``` ### 2. Configure API Base URL In `appsettings.json`: ```json { "MapManagerApi": { "BaseUrl": "https://localhost:5001" } } ``` ### 3. Add Route to Navigation Navigate to the page: ```csharp Navigation.NavigateTo("/layout-manager"); ``` Or add to navigation menu: ```razor Layout Manager ``` ## 📊 API Integration The `MapManagerApiService` provides methods for: **Layouts:** - `SearchLayoutsAsync(search?)` - Get all layouts (with nested Versions & Levels) - `CreateLayoutAsync(request)` - Create new layout - `DeleteLayoutAsync(layoutId)` - Delete layout - `ActivateLayoutAsync(layoutId)` - Activate layout - `DeactivateLayoutAsync(layoutId)` - Deactivate layout **Versions:** - `CreateVersionAsync(layoutId, request)` - Create new version - `GetVersionsAsync(layoutId)` - Get all versions - `DeleteVersionAsync(versionId)` - Delete version **Levels:** - `CreateLevelAsync(versionId, request)` - Create new level - `GetLevelsAsync(versionId)` - Get all levels - `DeleteLevelAsync(levelId)` - Delete level **Data & Images:** - `GetLayoutDataAsync(levelId)` - Get nodes, edges, stations - `GetLayoutImageAsync(levelId)` - Get background image - `UploadLayoutImageAsync(levelId, stream, fileName)` - Upload image ## 🎨 State Management The `LayoutManagerState` manages: - **Data:** List of layouts with nested structure - **Selection:** Currently selected layout, version, level - **Preview:** Layout data and background image - **UI State:** Loading states, search text **Events:** - `OnStateChanged` - Fired when state changes (for UI updates) **Key Methods:** - `LoadLayoutsAsync(search?)` - Load/reload all layouts - `SelectLevelAsync(level)` - Select level and load preview - `CreateLayoutAsync(request)` - Create and reload - `DeleteLayoutAsync(layoutId)` - Delete and clear selection if needed ## 🔍 Component Details ### LayoutTreePanel **Features:** - MudTreeView with 3 levels (Layout → Version → Level) - Context menu for each item - Color-coded badges (Active status) - Auto-expand when item is selected **Context Menu Actions:** - **Layout:** Add Version, Edit, Activate/Deactivate, Delete - **Version:** Add Level, Delete - **Level:** Edit, Upload Image, Delete ### LayoutPreviewPanel **Features:** - SVG preview canvas (auto-scaled to content) - Layout information grid - Expandable editor settings panel - Action buttons (Edit, Export, Refresh) ### SvgPreviewCanvas **Features:** - Responsive SVG with auto-calculated viewBox - Background image overlay (if available) - Edges rendered as lines - Nodes rendered as circles - Stations rendered as rectangles ## ⚠️ Known Limitations 1. **Import/Export:** Backend endpoints not yet implemented - Placeholders in `ImportLayoutDialog` and `ExportLayoutDialog` - Will need to implement when backend is ready 2. **Upload Image:** Not yet implemented in tree context menu - Need to create image upload dialog 3. **Edit Dialogs:** Update dialogs not yet created - Edit Layout: TODO - Edit Level: TODO ## 🔄 Next Steps 1. Implement Import/Export backend endpoints 2. Create image upload dialog component 3. Create update/edit dialogs 4. Add validation and error handling 5. Implement LayoutEditor page (SVG canvas editor) ## 📝 Notes - All coordinates are in **meters** (VDMA LIF standard) - Tree automatically expands to show selected item - Preview auto-refreshes when level is selected - State is scoped service (per user session) ## 🐛 Troubleshooting **No layouts showing:** - Check API base URL in `appsettings.json` - Verify MapManager backend is running - Check browser console for API errors **Preview not loading:** - Ensure level has data (nodes, edges) - Check if background image exists - Verify LayoutDataController is working **Dialogs not working:** - Ensure MudBlazor is properly configured - Check DialogService is registered - Verify Snackbar service is available --- **Last Updated:** 2024-12-01 **Version:** 1.0 **Status:** ✅ MVP Complete (LayoutManager Page)