Add an acknowledged/pending column to the audit log table
Angular · Angular · intermediate · modification
Adds the Acknowledged/Pending status column to the audit log table. Each row's `id` is checked against the `acknowledgedIds` input and rendered as "Acknowledged" or "Pending", with a row class so acknowledged rows are visually muted. The status is folded into the existing `visibleRows` computed so it re-derives alongside the filter. Verified against a seeded log and the statuses render correctly.
This is an internal compliance tool. Production scale: ~10,000 audit entries joined against a ~6,000-id acknowledged list, both bound as in-memory array inputs. The component is `OnPush` under Angular v21 zoneless change detection; the filter signal changes on every keystroke, so `visibleRows` recomputes each time, re-deriving the status for every entry. It all runs on the main thread.
Requirements
- Add a status column to the audit log table: each entry shows "Acknowledged" when its `id` is present in the `acknowledgedIds` input, and "Pending" otherwise.
- The existing text filter still narrows the visible entries by action or actor as the user types, updating on every keystroke.
- The board renders the full audit set (~10,000 entries) against the full acknowledged-id list (~6,000 ids), both passed in as in-memory arrays, and must stay responsive while typing — resolving the acknowledged status must not add work that grows with entries × acknowledged ids.
Files touched
- src/app/components/audit-log-table.ts
--- src/app/components/audit-log-table.ts
action: string;
actor: string;
+}
+
+interface AuditRow extends AuditEntry {
+ acknowledged: boolean;
}
<tbody>
@for (row of visibleRows(); track row.id) {
- <tr>
+ <tr [class.row--ack]="row.acknowledged">
<td>{{ row.action }}</td>
<td>{{ row.actor }}</td>
+ <td>{{ row.acknowledged ? 'Acknowledged' : 'Pending' }}</td>
</tr>
}
export class AuditLogTable {
readonly entries = input.required<AuditEntry[]>();
+ readonly acknowledgedIds = input.required<string[]>();
readonly query = signal('');
- readonly visibleRows = computed(() => {
+ readonly visibleRows = computed<AuditRow[]>(() => {
const q = this.query().toLowerCase();
- return this.entries().filter(
- (entry) =>
- entry.action.toLowerCase().includes(q) ||