feat: minimal signals + RemoteData template with a users feature
Extracted from atomic-design-poc: RemoteData<E,T> (bare union + fromResource, no combinators) + a trimmed <app-async> switch, no Elm-style store — state is resource() plus one plain signal. Minimal DDD layering per context (domain/infrastructure/application/ui) combined with atomic design inside ui/ (atoms/molecules/organisms/templates/pages), mirroring the POC's conventions at template scale. One worked feature (users/): a list with a click-through to a detail view (its own independent resource() fetch) and a Back action. Tests are BDD-style (describe/it, one assertion per it) and black-box (assert rendered DOM/emitted events only) - 100% branch/line coverage. README.md documents what's deliberately omitted vs. the POC and the concrete growth path back to it. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,31 @@
|
||||
import { Component, computed, signal } from '@angular/core';
|
||||
import { PageShellComponent } from '@shared/ui/templates/page-shell.component';
|
||||
import { AsyncComponent } from '@shared/ui/molecules/async.component';
|
||||
import { fromResource } from '@shared/application/remote-data';
|
||||
import { UserListComponent } from '@users/ui/organisms/user-list.component';
|
||||
import { UserDetailComponent } from '@users/ui/organisms/user-detail.component';
|
||||
import { usersResource } from '@users/application/users.resource';
|
||||
import { isEmptyUserList } from '@users/domain/user';
|
||||
|
||||
@Component({
|
||||
selector: 'app-users-page',
|
||||
imports: [PageShellComponent, AsyncComponent, UserListComponent, UserDetailComponent],
|
||||
template: `
|
||||
<app-page-shell heading="Users">
|
||||
@if (selectedUserId(); as id) {
|
||||
<app-user-detail [userId]="id" (close)="selectedUserId.set(null)" />
|
||||
} @else {
|
||||
<app-async [data]="listData()" (retry)="usersResource.reload()">
|
||||
@if (usersResource.hasValue()) {
|
||||
<app-user-list [users]="usersResource.value()!" (select)="selectedUserId.set($event)" />
|
||||
}
|
||||
</app-async>
|
||||
}
|
||||
</app-page-shell>
|
||||
`,
|
||||
})
|
||||
export class UsersPage {
|
||||
protected selectedUserId = signal<number | null>(null);
|
||||
protected usersResource = usersResource();
|
||||
protected listData = computed(() => fromResource(this.usersResource, isEmptyUserList));
|
||||
}
|
||||
Reference in New Issue
Block a user