COMPONENT USAGE
Ecosistema completo para organización y gestión de contenido con interfaces espaciales
User Management Components - Usage Guide
Complete guide for using the user-management module components in your Angular 20 application.
Table of Contents
- Installation
- Components Overview
- Usage Examples
- State Management
- Events Integration
- Security & Permissions
Installation
// In your app routes or feature module
import { userManagementRoutes } from '@libs-core/user-management';
export const routes: Routes = [
{
path: 'users',
loadChildren: () => userManagementRoutes,
canActivate: [authGuard],
},
];
Components Overview
1. UserListComponent
Displays a paginated, filterable list of users with bulk operations.
Selector: lib-user-list
Features:
- Search and advanced filtering
- Sortable columns
- Pagination
- Bulk selection and operations
- Status indicators
- Role badges
Usage:
import { UserListComponent } from '@libs-core/user-management';
@Component({
standalone: true,
imports: [UserListComponent],
template: `<lib-user-list />`
})
export class UsersPageComponent {}
Inputs: None (uses NGXS state)
Outputs: None (uses NGXS actions)
Example with Custom Container:
@Component({
template: `
<div class="users-container">
<h1>User Management</h1>
<lib-user-list />
</div>
`
})
export class UsersPageComponent {}
2. UserDetailComponent
Shows detailed information about a specific user.
Selector: lib-user-detail
Features:
- Complete user profile display
- Role and permission visualization
- Activity history
- Status badges
- Edit mode toggle
Usage:
import { UserDetailComponent } from '@libs-core/user-management';
@Component({
standalone: true,
imports: [UserDetailComponent],
template: `<lib-user-detail />`
})
export class UserProfileComponent {}
Route Integration:
{
path: 'users/:id',
component: UserDetailComponent,
canActivate: [authGuard, permissionGuard('users:read')]
}
3. UserFormComponent
Form for creating and editing users with validation.
Selector: lib-user-form
Features:
- Reactive forms with validation
- Email format validation
- Username uniqueness check
- Role selection
- Status management
- Error handling
Usage:
import { UserFormComponent } from '@libs-core/user-management';
@Component({
standalone: true,
imports: [UserFormComponent],
template: `
<lib-user-form
[mode]="mode()"
(submitted)="handleSubmit($event)"
(cancelled)="handleCancel()" />
`
})
export class CreateUserComponent {
mode = signal<'create' | 'edit'>('create');
handleSubmit(user: CreateUserRequest) {
console.log('User created:', user);
}
handleCancel() {
console.log('Form cancelled');
}
}
Inputs:
mode:'create' | 'edit'- Form modeinitialData?:User- For edit mode
Outputs:
submitted: EmitsCreateUserRequest | UpdateUserRequestcancelled: Emits when form is cancelled
4. UserCardComponent
Compact user display card with actions.
Selector: lib-user-card
Features:
- Avatar display
- Role badge
- Status indicator
- Quick actions menu
- Responsive design
Usage:
import { UserCardComponent } from '@libs-core/user-management';
@Component({
template: `
@for (user of users(); track user.id) {
<lib-user-card
[user]="user"
(viewDetails)="viewUser($event)"
(edit)="editUser($event)"
(delete)="deleteUser($event)" />
}
`
})
export class UserGridComponent {
users = signal<User[]>([]);
viewUser(userId: string) {
this.router.navigate(['/users', userId]);
}
editUser(userId: string) {
this.router.navigate(['/users', userId, 'edit']);
}
deleteUser(userId: string) {
// Handle delete
}
}
Inputs:
user:User- User data to display (required)compact?:boolean- Compact mode (default: false)
Outputs:
viewDetails: Emits user IDedit: Emits user IDdelete: Emits user ID
5. UserAvatarComponent
User avatar with fallback to initials.
Selector: lib-user-avatar
Features:
- Image avatar with error handling
- Initials fallback
- Multiple sizes
- Status indicator overlay
- Accessibility support
Usage:
import { UserAvatarComponent } from '@libs-core/user-management';
@Component({
template: `
<lib-user-avatar
[user]="user()"
[size]="'large'"
[showStatus]="true" />
`
})
export class ProfileHeaderComponent {
user = signal<User | null>(null);
}
Inputs:
user:User- User data (required)size?:'small' | 'medium' | 'large'- Avatar size (default: 'medium')showStatus?:boolean- Show status indicator (default: false)
Sizes:
small: 32x32pxmedium: 48x48px (default)large: 64x64px
6. UserFilterComponent
Advanced filtering UI for user lists.
Selector: lib-user-filter
Features:
- Search input
- Status filter
- Role filter
- Date range picker
- Advanced operators
- Filter reset
Usage:
import { UserFilterComponent } from '@libs-core/user-management';
@Component({
template: `
<lib-user-filter
[filters]="currentFilters()"
(filtersChanged)="applyFilters($event)"
(reset)="resetFilters()" />
`
})
export class UserSearchComponent {
currentFilters = signal<UserFilters>({});
applyFilters(filters: UserFilters) {
this.currentFilters.set(filters);
this.store.dispatch(new SetFilters(filters));
}
resetFilters() {
this.currentFilters.set({});
this.store.dispatch(new ClearFilters());
}
}
Inputs:
filters?:UserFilters- Current filter values
Outputs:
filtersChanged: EmitsUserFiltersreset: Emits when filters are reset
Filter Options:
interface UserFilters {
search?: string; // Name, email, username
status?: UserStatus[]; // active, inactive, suspended, pending
roleIds?: string[]; // Role IDs
createdAfter?: string; // ISO date string
createdBefore?: string; // ISO date string
lastActiveAfter?: string; // ISO date string
advancedFilters?: AdvancedFilter[]; // Custom filters
}
7. UserStatusBadgeComponent
Displays user status with color coding.
Selector: lib-user-status-badge
Features:
- Color-coded status display
- Icon indicators
- Tooltip with last active time
- Accessibility labels
Usage:
import { UserStatusBadgeComponent } from '@libs-core/user-management';
@Component({
template: `
<lib-user-status-badge
[status]="user().status"
[lastActive]="user().lastActive" />
`
})
export class UserStatusComponent {
user = signal<User>({...});
}
Inputs:
status:UserStatus- User status (required)lastActive?:string- Last active timestamp
Status Colors:
active: Green (#059669)inactive: Gray (#6b7280)suspended: Red (#dc2626)pending: Yellow (#f59e0b)
8. UserRoleManagerComponent
Role assignment and management UI.
Selector: lib-user-role-manager
Features:
- Multi-role selection
- Primary role designation
- Role hierarchy visualization
- Permission display per role
- Change tracking
- Validation
Usage:
import { UserRoleManagerComponent } from '@libs-core/user-management';
@Component({
template: `
<lib-user-role-manager
[user]="user()"
[availableRoles]="availableRoles()"
[readonly]="!canEditRoles()"
(rolesChanged)="handleRolesChanged($event)"
(primaryRoleChanged)="handlePrimaryRoleChanged($event)" />
`
})
export class EditUserRolesComponent {
user = signal<User>({...});
availableRoles = signal<SystemRoles[]>([
SystemRoles.ADMIN,
SystemRoles.MANAGER,
SystemRoles.USER,
SystemRoles.VIEWER,
]);
canEditRoles = signal(true);
handleRolesChanged(roleIds: string[]) {
console.log('Roles changed:', roleIds);
// Update user roles
}
handlePrimaryRoleChanged(primaryRole: SystemRoles) {
console.log('Primary role changed:', primaryRole);
// Update primary role
}
}
Inputs:
user:User- User to manage roles for (required)availableRoles?:SystemRoles[]- Available system rolesreadonly?:boolean- Read-only mode (default: false)
Outputs:
rolesChanged: Emitsstring[]- New role IDsprimaryRoleChanged: EmitsSystemRoles- New primary role
Role Hierarchy:
- ADMIN (Level 4) - Full administrative access
- MANAGER (Level 3) - Team and resource management
- USER (Level 2) - Standard user access
- VIEWER (Level 1) - Read-only access
State Management
All components integrate with NGXS state. Here's how to dispatch actions and select data:
Dispatching Actions
import { Store } from '@ngxs/store';
import * as UserActions from '@libs-core/user-management';
export class MyComponent {
private store = inject(Store);
loadUsers() {
this.store.dispatch(new UserActions.LoadUsers());
}
createUser(request: CreateUserRequest) {
this.store.dispatch(new UserActions.CreateUser(request));
}
updateUser(request: UpdateUserRequest) {
this.store.dispatch(new UserActions.UpdateUser(request));
}
deleteUser(userId: string) {
this.store.dispatch(new UserActions.DeleteUser(userId));
}
selectUser(user: User) {
this.store.dispatch(new UserActions.SelectUser(user));
}
setFilters(filters: UserFilters) {
this.store.dispatch(new UserActions.SetFilters(filters));
}
bulkUpdate(request: BulkOperationRequest) {
this.store.dispatch(new UserActions.BulkUpdateUsers(request));
}
}
Selecting State
import { UserState } from '@libs-core/user-management';
export class MyComponent {
private store = inject(Store);
users$ = this.store.select(UserState.getUsers);
selectedUser$ = this.store.select(UserState.getSelectedUser);
loading$ = this.store.select(UserState.isLoading);
error$ = this.store.select(UserState.getError);
filters$ = this.store.select(UserState.getFilters);
bulkSelection$ = this.store.select(UserState.getBulkSelection);
total$ = this.store.select(UserState.getTotal);
}
Using Signals with NGXS
import { toSignal } from '@angular/core/rxjs-interop';
export class MyComponent {
private store = inject(Store);
users = toSignal(this.store.select(UserState.getUsers), { initialValue: [] });
loading = toSignal(this.store.select(UserState.isLoading), { initialValue: false });
error = toSignal(this.store.select(UserState.getError), { initialValue: null });
}
Events Integration
Subscribe to domain events for cross-module coordination:
import { EventBusService } from '@libs-core/event-system';
import {
UserCreatedEvent,
UserUpdatedEvent,
UserDeletedEvent
} from '@libs-core/user-management';
export class NotificationService {
private eventBus = inject(EventBusService);
constructor() {
this.subscribeToUserEvents();
}
private subscribeToUserEvents() {
// User created
this.eventBus.subscribe(UserCreatedEvent, (event) => {
console.log('User created:', event.payload.user);
this.showNotification(`New user ${event.payload.user.email} created`);
});
// User updated
this.eventBus.subscribe(UserUpdatedEvent, (event) => {
console.log('User updated:', event.payload.user);
this.showNotification(`User ${event.payload.user.email} updated`);
});
// User deleted
this.eventBus.subscribe(UserDeletedEvent, (event) => {
console.log('User deleted:', event.payload.userId);
this.showNotification(`User deleted`);
});
}
private showNotification(message: string) {
// Show notification to user
}
}
Security & Permissions
Route Protection
import { authGuard, permissionGuard, roleGuard } from '@libs-core/security';
import { SystemRoles } from '@libs-core/shared-models';
export const routes: Routes = [
{
path: 'users',
canActivate: [authGuard],
children: [
{
path: '',
component: UserListComponent,
canActivate: [permissionGuard('users:read')],
},
{
path: 'create',
component: UserFormComponent,
canActivate: [permissionGuard('users:create')],
},
{
path: ':id/edit',
component: UserFormComponent,
canActivate: [permissionGuard('users:update')],
},
{
path: 'admin',
component: UserListComponent,
canActivate: [
roleGuard(SystemRoles.ADMIN),
permissionGuard('users:manage'),
],
},
],
},
];
Permission Checks in Components
import { PermissionService } from '@libs-core/security';
export class UserActionsComponent {
private permissionService = inject(PermissionService);
canCreate = this.permissionService.hasPermission('users:create');
canUpdate = this.permissionService.hasPermission('users:update');
canDelete = this.permissionService.hasPermission('users:delete');
canManage = this.permissionService.hasPermission('users:manage');
}
Multi-Tenant Context
All operations automatically use tenant context from ContextService:
import { ContextService } from '@libs-core/security';
export class UserService {
private contextService = inject(ContextService);
getCurrentTenant() {
const context = this.contextService.getCurrentContext();
return context.tenantId; // Used automatically in all API calls
}
}
Best Practices
1. Use Standalone Components
All components are standalone - import directly where needed:
import { UserListComponent } from '@libs-core/user-management';
@Component({
standalone: true,
imports: [UserListComponent],
// ...
})
2. Leverage Signals
Use Angular signals for reactive data:
export class UserComponent {
users = toSignal(this.store.select(UserState.getUsers));
filteredUsers = computed(() => {
return this.users().filter(u => u.status === 'active');
});
}
3. Handle Errors Gracefully
export class UserComponent {
error = toSignal(this.store.select(UserState.getError));
ngOnInit() {
effect(() => {
const errorMessage = this.error();
if (errorMessage) {
this.showErrorNotification(errorMessage);
}
});
}
}
4. Clean Up Subscriptions
Event subscriptions are automatically cleaned up, but for custom observables:
export class UserComponent implements OnDestroy {
private destroy$ = new Subject<void>();
ngOnInit() {
this.customObservable$
.pipe(takeUntil(this.destroy$))
.subscribe(/*...*/);
}
ngOnDestroy() {
this.destroy$.next();
this.destroy$.complete();
}
}
5. Use OnPush Change Detection
All components use OnPush - ensure immutability:
@Component({
changeDetection: ChangeDetectionStrategy.OnPush,
// ...
})
export class UserComponent {
updateUser(user: User) {
// Create new object instead of mutating
const updated = { ...user, firstName: 'New Name' };
this.store.dispatch(new UpdateUser(updated));
}
}
Styling & Theming
Components use CSS variables for easy theming:
:root {
/* Primary colors */
--primary-color: #3b82f6;
--primary-hover: #2563eb;
/* Status colors */
--status-active: #059669;
--status-inactive: #6b7280;
--status-suspended: #dc2626;
--status-pending: #f59e0b;
/* Role colors */
--role-admin-bg: #dc2626;
--role-manager-bg: #2563eb;
--role-user-bg: #059669;
--role-viewer-bg: #6b7280;
/* Spacing */
--spacing-xs: 0.25rem;
--spacing-sm: 0.5rem;
--spacing-md: 1rem;
--spacing-lg: 1.5rem;
--spacing-xl: 2rem;
}
Accessibility
All components follow WCAG 2.1 Level AA:
- ✅ Semantic HTML
- ✅ ARIA labels and roles
- ✅ Keyboard navigation
- ✅ Focus management
- ✅ Screen reader support
- ✅ Color contrast compliance
Example:
<!-- UserCardComponent template -->
<article
role="article"
aria-label="User card for John Doe"
tabindex="0">
<!-- Content -->
</article>
Troubleshooting
Component Not Rendering
Check that you've imported the component:
import { UserListComponent } from '@libs-core/user-management';
@Component({
imports: [UserListComponent], // Must be in imports array
})
State Not Updating
Ensure NGXS is configured in your app:
import { provideStore } from '@ngxs/store';
import { UserState } from '@libs-core/user-management';
export const appConfig: ApplicationConfig = {
providers: [
provideStore([UserState]),
// ...
],
};
Events Not Firing
Verify EventBusService is provided:
import { provideEventSystem } from '@libs-core/event-system';
export const appConfig: ApplicationConfig = {
providers: [
provideEventSystem(),
// ...
],
};
Support
For issues, feature requests, or questions, please refer to:
- Project documentation
- Component source code
- NGXS documentation: https://www.ngxs.io/
- Angular documentation: https://angular.dev/