up-app/src/app/pages/<entity>-search/<entity>-search.component.ts (standalone component):
- Use
signal<Entity[]>([])to store the items list; on data fetch, call.set()to update. - On init, call
<entity>Service.getAll()andthis.items.set(data)to update signal. - Header bar with an Add button →
router.navigate(['/<entity>/new']). - Per row (use
@forwithtrack item.id):- Edit button →
router.navigate(['/<entity>', item.id, 'edit']) - Delete button → show confirmation popup; if confirmed, call
<entity>Service.delete(id)and update signal with.set()on success.
- Edit button →
Route table (app.routes.ts) — add the routes the form page will use:
{ path: '<entity>', component: <Entity>SearchComponent },
{ path: '<entity>/new', component: <Entity>FormComponent },
{ path: '<entity>/:id/edit', component: <Entity>FormComponent },
Component TypeScript (signal pattern):
import { signal } from '@angular/core';
export class <Entity>SearchComponent {
items = signal<<Entity>[]>([]);
constructor(
private router: Router,
private <entity>Service: <Entity>Service
) {}
ngOnInit() {
this.<entity>Service.getAll().subscribe(data => {
this.items.set(data);
});
}
onEdit(id: number) {
this.router.navigate(['/<entity>', id, 'edit']);
}
onDelete(item: <Entity>) {
if (confirm(`Delete "${item.name}"?`)) {
this.<entity>Service.delete(item.id).subscribe(() => {
const current = this.items();
this.items.set(current.filter(i => i.id !== item.id));
});
}
}
}
Template (with @for control flow):
<div class="space-y-4">
<button (click)="onAdd()" class="bg-blue-500 text-white px-4 py-2 rounded">
Add
</button>
<div class="overflow-x-auto">
<table class="min-w-full border-collapse border border-gray-300">
<thead>
<tr class="bg-gray-100">
<th class="border border-gray-300 px-4 py-2">Name</th>
<th class="border border-gray-300 px-4 py-2">Actions</th>
</tr>
</thead>
<tbody>
@for (item of items(); track item.id) {
<tr>
<td class="border border-gray-300 px-4 py-2">{{ item.name }}</td>
<td class="border border-gray-300 px-4 py-2">
<button (click)="onEdit(item.id)" class="text-blue-600 mr-2">Edit</button>
<button (click)="onDelete(item)" class="text-red-600">Delete</button>
</td>
</tr>
}
</tbody>
</table>
</div>
</div>
Redeploy from the project root:
docker compose up -d --build
Verify: search page loads real up-api data with Add/Edit/Delete buttons on rows. Click Delete → confirm popup → row removed from table.