bharat_erp/lib/modules/rbac/presentation/providers/rbac_provider.dart

187 lines
5.5 KiB
Dart

import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../../../../core/utils/table_search.dart';
import '../../domain/entities/rbac_entities.dart';
enum RbacTab { users, roles, permissions }
class RbacState {
const RbacState({
this.users = const [],
this.roles = const [],
this.selectedTab = RbacTab.users,
this.selectedRoleId = 'super_admin',
this.searchQuery = '',
this.roleFilter = 'All Roles',
this.departmentFilter = 'All Departments',
this.statusFilter = 'All Statuses',
this.currentPage = 0,
this.pageSize = 10,
});
final List<ManagedUser> users;
final List<ManagedRole> roles;
final RbacTab selectedTab;
final String selectedRoleId;
final String searchQuery;
final String roleFilter;
final String departmentFilter;
final String statusFilter;
final int currentPage;
final int pageSize;
int get totalUsers => users.length;
int get activeUsers =>
users.where((u) => u.status == UserAccountStatus.active).length;
int get inactiveUsers =>
users.where((u) => u.status == UserAccountStatus.inactive).length;
int get lockedUsers =>
users.where((u) => u.status == UserAccountStatus.locked).length;
List<ManagedUser> get filteredUsers {
return users.where((user) {
final q = searchQuery.toLowerCase();
final matchesSearch = q.isEmpty ||
user.name.toLowerCase().contains(q) ||
user.email.toLowerCase().contains(q) ||
user.employeeCode.toLowerCase().contains(q);
final matchesRole =
roleFilter == 'All Roles' || user.roleName == roleFilter;
final matchesDept = departmentFilter == 'All Departments' ||
user.department == departmentFilter;
final matchesStatus = statusFilter == 'All Statuses' ||
user.status.label == statusFilter;
return matchesSearch && matchesRole && matchesDept && matchesStatus;
}).toList();
}
List<ManagedUser> get pagedUsers {
final filtered = filteredUsers;
final start = currentPage * pageSize;
if (start >= filtered.length) return [];
final end = (start + pageSize).clamp(0, filtered.length);
return filtered.sublist(start, end);
}
int get totalPages => (filteredUsers.length / pageSize).ceil().clamp(1, 999);
ManagedRole? get selectedRole {
for (final role in roles) {
if (role.id == selectedRoleId) return role;
}
return roles.isNotEmpty ? roles.first : null;
}
RbacState copyWith({
List<ManagedUser>? users,
List<ManagedRole>? roles,
RbacTab? selectedTab,
String? selectedRoleId,
String? searchQuery,
String? roleFilter,
String? departmentFilter,
String? statusFilter,
int? currentPage,
int? pageSize,
}) {
return RbacState(
users: users ?? this.users,
roles: roles ?? this.roles,
selectedTab: selectedTab ?? this.selectedTab,
selectedRoleId: selectedRoleId ?? this.selectedRoleId,
searchQuery: searchQuery ?? this.searchQuery,
roleFilter: roleFilter ?? this.roleFilter,
departmentFilter: departmentFilter ?? this.departmentFilter,
statusFilter: statusFilter ?? this.statusFilter,
currentPage: currentPage ?? this.currentPage,
pageSize: pageSize ?? this.pageSize,
);
}
}
final rbacProvider = StateNotifierProvider<RbacNotifier, RbacState>((ref) {
return RbacNotifier();
});
class RbacNotifier extends StateNotifier<RbacState> {
RbacNotifier()
: super(RbacState(
users: List.of(defaultUsers),
roles: List.of(defaultRoles),
)) {
_recountRoleUsers();
}
void setTab(RbacTab tab) => state = state.copyWith(selectedTab: tab, currentPage: 0);
void setSearch(String query) =>
state = state.copyWith(searchQuery: TableSearch.normalize(query), currentPage: 0);
void setRoleFilter(String filter) =>
state = state.copyWith(roleFilter: filter, currentPage: 0);
void setDepartmentFilter(String filter) =>
state = state.copyWith(departmentFilter: filter, currentPage: 0);
void setStatusFilter(String filter) =>
state = state.copyWith(statusFilter: filter, currentPage: 0);
void setPage(int page) => state = state.copyWith(currentPage: page);
void selectRole(String roleId) => state = state.copyWith(selectedRoleId: roleId);
void togglePermission(String module, RbacAction action) {
final role = state.selectedRole;
if (role == null) return;
final key = permissionKey(module, action);
final updated = Set<String>.from(role.permissions);
if (updated.contains(key)) {
updated.remove(key);
} else {
updated.add(key);
}
final roles = state.roles.map((r) {
if (r.id == role.id) return r.copyWith(permissions: updated);
return r;
}).toList();
state = state.copyWith(roles: roles);
}
void savePermissions() {
// Permissions already in state; would sync to API here.
}
void addUser(ManagedUser user) {
state = state.copyWith(users: [...state.users, user]);
_recountRoleUsers();
}
void addRole(ManagedRole role) {
state = state.copyWith(
roles: [...state.roles, role],
selectedRoleId: role.id,
);
}
void deleteRole(String roleId) {
if (roleId == 'super_admin') return;
state = state.copyWith(
roles: state.roles.where((r) => r.id != roleId).toList(),
);
_recountRoleUsers();
}
void _recountRoleUsers() {
final roles = state.roles.map((role) {
final count =
state.users.where((u) => u.roleId == role.id).length;
return role.copyWith(userCount: count);
}).toList();
state = state.copyWith(roles: roles);
}
}