mirror of
https://dev.azure.com/hugendubel/ISA/_git/ISA-Frontend
synced 2025-12-28 22:42:11 +01:00
Consolidate and rename skills to shorter, more intuitive names: - css-keyframes-animations → css-animations - api-sync-manager → api-sync - architecture-documentation → arch-docs - jest-vitest-patterns → test-migration - reactive-state-patterns → state-patterns - library-scaffolder → library-creator Merge related skills: - angular-template + html-template → template-standards - angular-effects-alternatives + ngrx-resource-api → state-patterns Remove obsolete skills: - architecture-enforcer (merged into architecture-validator) - circular-dependency-resolver (merged into architecture-validator) - standalone-component-migrator (merged into migration-specialist agent) - swagger-sync-manager (replaced by api-sync) - api-change-analyzer (merged into api-sync) - type-safety-engineer (content distributed to relevant skills) - test-migration-specialist (replaced by migration-specialist agent) Add migration-specialist agent for standalone and test migrations. Update all cross-references in CLAUDE.md and agents.
3.5 KiB
3.5 KiB
Control Flow Reference
Advanced patterns for @if, @for, @switch.
@if Patterns
Store Results with as
@if (user.profile?.settings?.theme; as theme) {
<p>Theme: {{theme}}</p>
}
@if (data$ | async; as data) {
<app-list [items]="data.items" />
}
Complex Conditions
@if (isAdmin() && hasPermission('edit')) {
<button (click)="edit()">Edit</button>
}
@if (user()?.role === 'admin' || user()?.role === 'moderator') {
<app-moderation-panel />
}
@for Patterns
Contextual Variables
@for (user of users(); track user.id) {
<tr [class.odd]="$odd">
<td>{{$index + 1}}</td>
<td>{{user.name}}</td>
<td>{{$count}} total</td>
@if ($first) { <span>First</span> }
</tr>
}
Track Strategies
// ✅ Best: Unique ID
@for (order of orders(); track order.uuid) { }
// ✅ Good: Composite key
@for (item of items(); track item.categoryId + '-' + item.id) { }
// ⚠️ OK: Index (static only)
@for (color of ['red', 'blue']; track $index) { }
// ❌ NEVER: Identity function
@for (item of items(); track identity(item)) { }
Nested Loops
@for (category of categories(); track category.id) {
<div class="category">
<h3>{{category.name}}</h3>
@for (product of category.products; track product.id) {
<app-product [product]="product" [categoryIdx]="$index" />
}
</div>
}
Filter in Component
// Component
activeUsers = computed(() => this.users().filter(u => u.isActive));
// Template
@for (user of activeUsers(); track user.id) {
<app-user-card [user]="user" />
} @empty {
<p>No active users</p>
}
@switch Patterns
Basic Switch
@switch (viewMode()) {
@case ('grid') { <app-grid-view /> }
@case ('list') { <app-list-view /> }
@case ('table') { <app-table-view /> }
@default { <app-grid-view /> }
}
Nested Switch
@switch (category()) {
@case ('electronics') {
@switch (subcategory()) {
@case ('phones') { <app-phone-list /> }
@case ('laptops') { <app-laptop-list /> }
@default { <app-electronics-list /> }
}
}
@case ('clothing') { <app-clothing-list /> }
@default { <app-all-categories /> }
}
Combined with Other Control Flow
@switch (status()) {
@case ('loading') { <mat-spinner /> }
@case ('success') {
@if (data()?.length) {
@for (item of data(); track item.id) {
<app-item [item]="item" />
}
} @else {
<p>No data</p>
}
}
@case ('error') { <app-error [message]="errorMessage()" /> }
}
Common Patterns
Loading State
@if (isLoading()) {
<mat-spinner />
} @else if (error()) {
<app-error [error]="error()" (retry)="loadData()" />
} @else {
@for (item of items(); track item.id) {
<app-item [item]="item" />
} @empty {
<app-empty-state />
}
}
Tab Navigation
<nav>
@for (tab of tabs(); track tab.id) {
<button [class.active]="activeTab() === tab.id" (click)="setActiveTab(tab.id)">
{{tab.label}}
</button>
}
</nav>
@switch (activeTab()) {
@case ('profile') { <app-profile /> }
@case ('settings') { <app-settings /> }
@default { <app-profile /> }
}
Hierarchical Data
@for (section of sections(); track section.id) {
<details [open]="section.isExpanded">
<summary>{{section.title}} ({{section.items.length}})</summary>
@for (item of section.items; track item.id) {
<div>{{item.name}}</div>
} @empty {
<p>No items</p>
}
</details>
}