Widget System - Navigation Routes Fixed
Complete fix of all navigation routes across widget libraries
Widget System - Navigation Routes Fixed π§
Status: β
COMPLETE
Date: November 16, 2025
Session: 155.3
π― Problem Summary
All navigation routes in the @libs-widgets system were using absolute hardcoded paths that didn't respect the space-aware routing structure (/space/:spaceSlug/widgets/...).
Issues Found
- β Absolute paths like
/ui-builder/widgets - β Absolute paths like
/space/widgets/create(missing space slug) - β Routes not using
relativeTo: this.route - β Routes not respecting current space context
β Solution Applied
Pattern: Use relative navigation with relativeTo: this.route for all widget system navigation.
Navigation Strategy
// β
CORRECT: Relative navigation
this.router.navigate(['workspace'], {
relativeTo: this.route
});
// β WRONG: Absolute hardcoded path
this.router.navigate(['/ui-builder/widgets/builder']);
π Files Fixed
1. Widget Showcase - Gallery Component
File: libs/libs-widgets/widget-showcase/src/lib/components/widget-gallery/widget-gallery.component.ts
Before:
openWidget(widgetId: string) {
this.router.navigate(['/ui-builder/widgets', widgetId]);
}
openWidgetBuilder() {
this.router.navigate(['/ui-builder/widgets/builder']);
}
After:
openWidget(widgetId: string) {
this.logger.info('[WidgetGallery] Opening widget', { widgetId });
// Navigate to widget demo (relative to current space)
this.router.navigate([widgetId], { relativeTo: this.route });
}
openWidgetBuilder() {
this.logger.info('[WidgetGallery] Opening widget builder');
// Navigate to widget builder (relative to current space)
this.router.navigate(['builder'], { relativeTo: this.route });
}
Routes:
[widgetId]β Navigates to/space/:spaceSlug/widgets/:widgetId['builder']β Navigates to/space/:spaceSlug/widgets/builder
2. Widget Showcase - Demo Component
File: libs/libs-widgets/widget-showcase/src/lib/components/widget-demo/widget-demo.component.ts
Before:
backToGallery() {
this.router.navigate(['/ui-builder/widgets']);
}
openWidgetBuilder() {
this.router.navigate(['/ui-builder/widgets/builder']);
}
After:
backToGallery() {
// Navigate back to widgets gallery (relative to current space)
this.router.navigate(['../..'], { relativeTo: this.route });
}
openWidgetBuilder() {
// Navigate to widget builder (relative to current space)
this.router.navigate(['../../builder'], { relativeTo: this.route });
}
Routes:
['../..']β From/widgets/:widgetIdto/widgets['../../builder']β From/widgets/:widgetIdto/widgets/builder
3. Widgets Manager - Dashboard Component
File: libs/libs-widgets/widgets-manager/src/lib/components/widgets-manager-dashboard/widgets-manager-dashboard.component.ts
Before:
createWidget(): void {
this.router.navigate(['/space/widgets/create']);
}
editWidget(widget: SpaceWidget): void {
this.router.navigate(['/space/widgets/edit', widget.id]);
}
After:
createWidget(): void {
console.log('[WidgetsManagerDashboard] Creating new widget...');
// Navigate to widget builder workspace (relative to current space)
this.router.navigate(['../builder/workspace'], { relativeTo: this.route });
}
editWidget(widget: SpaceWidget): void {
console.log('[WidgetsManagerDashboard] Editing widget:', widget.name);
// Navigate to widget builder edit mode (relative to current space)
this.router.navigate(['../builder/workspace/edit', widget.id], { relativeTo: this.route });
}
Routes:
['../builder/workspace']β From/widgets/managerto/widgets/builder/workspace['../builder/workspace/edit', id]β From/widgets/managerto/widgets/builder/workspace/edit/:id
4. Widget Builder - Builder Component
File: libs/libs-widgets/widget-builder/src/lib/components/widget-builder/widget-builder.component.ts
Before:
goBack(): void {
const spaceId = this.spaceId();
this.router.navigate([`/space/${spaceId}/widgets`]);
}
After:
goBack(): void {
// Navigate back to widgets gallery (relative to current space)
this.router.navigate(['../..'], { relativeTo: this.route });
}
Routes:
['../..']β From/widgets/builderto/widgets
5. Widget Builder - AI Generator Component
File: libs/libs-widgets/widget-builder/src/lib/components/ai-widget-generator/ai-widget-generator.component.ts
Before:
constructor(private router: Router) {}
generate() {
this.router.navigate(['/widget-builder/create']);
}
After:
constructor(
private router: Router,
private route: ActivatedRoute
) {}
generate() {
console.log('Generating widget from prompt:', this.prompt());
alert('AI generation coming soon! For now, use the manual builder.');
// Navigate to workspace (relative to current route)
this.router.navigate(['../workspace'], { relativeTo: this.route });
}
Import Added:
import { Router, ActivatedRoute } from '@angular/router';
Routes:
['../workspace']β From/widgets/builderto/widgets/builder/workspace
6. Widget Builder - Workspace Component
File: libs/libs-widgets/widget-builder/src/lib/components/widget-builder-workspace/widget-builder-workspace.component.ts
Status: β Already correct - Uses relative navigation:
cancel() {
this.logger.info('Widget builder cancelled');
this.router.navigate(['..'], { relativeTo: this.route });
}
7. Widget Templates Gallery
File: libs/libs-widgets/widget-builder/src/lib/components/widget-templates-gallery/widget-templates-gallery.component.ts
Status: β Already correct - Uses relative navigation:
createFromTemplate(type: WidgetType) {
this.scrollPosition.set(window.scrollY);
this.router.navigate(['workspace'], {
relativeTo: this.route,
queryParams: { type }
});
}
πΊοΈ Complete Route Map
Current Space Context: /space/:spaceSlug/widgets/
| Component | From Route | Action | Navigation | To Route |
|---|---|---|---|---|
| Widget Gallery | /widgets |
Open widget | [widgetId] |
/widgets/:widgetId |
| Widget Gallery | /widgets |
Open builder | ['builder'] |
/widgets/builder |
| Widget Demo | /widgets/:widgetId |
Back to gallery | ['../..'] |
/widgets |
| Widget Demo | /widgets/:widgetId |
Open builder | ['../../builder'] |
/widgets/builder |
| Templates Gallery | /widgets/builder |
Create from template | ['workspace'] |
/widgets/builder/workspace |
| Widgets Manager | /widgets/manager |
Create widget | ['../builder/workspace'] |
/widgets/builder/workspace |
| Widgets Manager | /widgets/manager |
Edit widget | ['../builder/workspace/edit', id] |
/widgets/builder/workspace/edit/:id |
| Widget Builder | /widgets/builder |
Go back | ['../..'] |
/widgets |
| AI Generator | /widgets/builder |
Generate | ['../workspace'] |
/widgets/builder/workspace |
| Workspace | /widgets/builder/workspace |
Cancel | ['..'] |
/widgets/builder |
π― Benefits
1. Space-Aware Navigation β
All routes now respect the current space context:
/space/my-space/widgets/builderβ/space/another-space/widgets/builderβ- No hardcoded space IDs
2. Route Flexibility β
Routes work regardless of:
- Space slug changes
- Route structure updates
- URL prefix changes
3. Maintainability β
- Single source of truth (route configuration)
- No hardcoded paths in components
- Easy to refactor route structure
4. Consistency β
- All components use the same pattern
- Predictable navigation behavior
- Clear relative path structure
π§ͺ Testing Checklist
From Widget Gallery (/space/:spaceSlug/widgets)
- Click widget card β Opens demo
- Click "Create Widget" β Opens builder templates
- Search works correctly
- Category filter works
From Widget Demo (/space/:spaceSlug/widgets/:widgetId)
- "Back to Gallery" β Returns to gallery
- "Open Builder" β Opens widget builder
From Widget Builder Templates (/space/:spaceSlug/widgets/builder)
- Click template β Opens workspace with type
- "Create from Scratch" β Opens workspace
- Back button β Returns to widgets gallery
From Widget Builder Workspace (/space/:spaceSlug/widgets/builder/workspace)
- Cancel β Returns to templates
- Save β Stays in workspace
- Publish β Emits event
From Widgets Manager (/space/:spaceSlug/widgets/manager)
- "Create Widget" β Opens builder workspace
- "Edit Widget" β Opens workspace in edit mode
- Widget list loads correctly
- Refresh button works
Cross-Library Navigation
- Gallery β Builder β Workspace β Gallery (full loop)
- Manager β Builder β Manager (edit flow)
- Demo β Builder β Demo (exploration flow)
π Summary
Files Modified: 5
- β
widget-gallery.component.ts - β
widget-demo.component.ts - β
widgets-manager-dashboard.component.ts - β
widget-builder.component.ts - β
ai-widget-generator.component.ts
Files Already Correct: 2
- β
widget-builder-workspace.component.ts - β
widget-templates-gallery.component.ts
Linter Errors: 0
β All files pass linter checks
Route Redirect Added
β
/widgets/widget-builder β /widgets/builder
π Status
Navigation Routes: β
FIXED
Linter Errors: β
NONE
Space-Aware: β
YES
Ready for Testing: β
YES
π Related Documentation
Fixed: November 16, 2025
Status: β
Complete and Ready
Next: Browser testing with real space navigation