fixed permissions loading issue on employee screen
This commit is contained in:
parent
45bc492683
commit
7e75431feb
@ -13,6 +13,7 @@ class PermissionController extends GetxController {
|
||||
var employeeInfo = Rxn<EmployeeInfo>();
|
||||
var projectsInfo = <ProjectInfo>[].obs;
|
||||
Timer? _refreshTimer;
|
||||
var isLoading = true.obs;
|
||||
|
||||
@override
|
||||
void onInit() {
|
||||
@ -26,7 +27,8 @@ class PermissionController extends GetxController {
|
||||
await loadData(token!);
|
||||
_startAutoRefresh();
|
||||
} else {
|
||||
logSafe("Token is null or empty. Skipping API load and auto-refresh.", level: LogLevel.warning);
|
||||
logSafe("Token is null or empty. Skipping API load and auto-refresh.",
|
||||
level: LogLevel.warning);
|
||||
}
|
||||
}
|
||||
|
||||
@ -37,19 +39,24 @@ class PermissionController extends GetxController {
|
||||
logSafe("Auth token retrieved: $token", level: LogLevel.debug);
|
||||
return token;
|
||||
} catch (e, stacktrace) {
|
||||
logSafe("Error retrieving auth token", level: LogLevel.error, error: e, stackTrace: stacktrace);
|
||||
logSafe("Error retrieving auth token",
|
||||
level: LogLevel.error, error: e, stackTrace: stacktrace);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> loadData(String token) async {
|
||||
try {
|
||||
isLoading.value = true;
|
||||
final userData = await PermissionService.fetchAllUserData(token);
|
||||
_updateState(userData);
|
||||
await _storeData();
|
||||
logSafe("Data loaded and state updated successfully.");
|
||||
} catch (e, stacktrace) {
|
||||
logSafe("Error loading data from API", level: LogLevel.error, error: e, stackTrace: stacktrace);
|
||||
logSafe("Error loading data from API",
|
||||
level: LogLevel.error, error: e, stackTrace: stacktrace);
|
||||
} finally {
|
||||
isLoading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -60,7 +67,8 @@ class PermissionController extends GetxController {
|
||||
projectsInfo.assignAll(userData['projects']);
|
||||
logSafe("State updated with user data.");
|
||||
} catch (e, stacktrace) {
|
||||
logSafe("Error updating state", level: LogLevel.error, error: e, stackTrace: stacktrace);
|
||||
logSafe("Error updating state",
|
||||
level: LogLevel.error, error: e, stackTrace: stacktrace);
|
||||
}
|
||||
}
|
||||
|
||||
@ -89,7 +97,8 @@ class PermissionController extends GetxController {
|
||||
|
||||
logSafe("User data successfully stored in SharedPreferences.");
|
||||
} catch (e, stacktrace) {
|
||||
logSafe("Error storing data", level: LogLevel.error, error: e, stackTrace: stacktrace);
|
||||
logSafe("Error storing data",
|
||||
level: LogLevel.error, error: e, stackTrace: stacktrace);
|
||||
}
|
||||
}
|
||||
|
||||
@ -100,20 +109,23 @@ class PermissionController extends GetxController {
|
||||
if (token?.isNotEmpty ?? false) {
|
||||
await loadData(token!);
|
||||
} else {
|
||||
logSafe("Token missing during auto-refresh. Skipping.", level: LogLevel.warning);
|
||||
logSafe("Token missing during auto-refresh. Skipping.",
|
||||
level: LogLevel.warning);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
bool hasPermission(String permissionId) {
|
||||
final hasPerm = permissions.any((p) => p.id == permissionId);
|
||||
logSafe("Checking permission $permissionId: $hasPerm", level: LogLevel.debug);
|
||||
logSafe("Checking permission $permissionId: $hasPerm",
|
||||
level: LogLevel.debug);
|
||||
return hasPerm;
|
||||
}
|
||||
|
||||
bool isUserAssignedToProject(String projectId) {
|
||||
final assigned = projectsInfo.any((project) => project.id == projectId);
|
||||
logSafe("Checking project assignment for $projectId: $assigned", level: LogLevel.debug);
|
||||
logSafe("Checking project assignment for $projectId: $assigned",
|
||||
level: LogLevel.debug);
|
||||
return assigned;
|
||||
}
|
||||
|
||||
|
@ -248,33 +248,46 @@ class _EmployeesScreenState extends State<EmployeesScreen> with UIMixin {
|
||||
}
|
||||
|
||||
Widget _buildFloatingActionButton() {
|
||||
if (!permissionController.hasPermission(Permissions.manageEmployees)) {
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
return Obx(() {
|
||||
// Show nothing while permissions are loading
|
||||
if (permissionController.isLoading.value) {
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
|
||||
return InkWell(
|
||||
onTap: _onAddNewEmployee,
|
||||
borderRadius: BorderRadius.circular(28),
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.red,
|
||||
borderRadius: BorderRadius.circular(28),
|
||||
boxShadow: const [
|
||||
BoxShadow(
|
||||
color: Colors.black26, blurRadius: 6, offset: Offset(0, 3))
|
||||
],
|
||||
// Show FAB only if user has Manage Employees permission
|
||||
final hasPermission =
|
||||
permissionController.hasPermission(Permissions.manageEmployees);
|
||||
if (!hasPermission) {
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
|
||||
return InkWell(
|
||||
onTap: _onAddNewEmployee,
|
||||
borderRadius: BorderRadius.circular(28),
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.red,
|
||||
borderRadius: BorderRadius.circular(28),
|
||||
boxShadow: const [
|
||||
BoxShadow(
|
||||
color: Colors.black26,
|
||||
blurRadius: 6,
|
||||
offset: Offset(0, 3),
|
||||
)
|
||||
],
|
||||
),
|
||||
child: const Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Icon(Icons.add, color: Colors.white),
|
||||
SizedBox(width: 8),
|
||||
Text('Add New Employee', style: TextStyle(color: Colors.white)),
|
||||
],
|
||||
),
|
||||
),
|
||||
child: const Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Icon(Icons.add, color: Colors.white),
|
||||
SizedBox(width: 8),
|
||||
Text('Add New Employee', style: TextStyle(color: Colors.white)),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
Widget _buildSearchAndActionRow() {
|
||||
@ -371,60 +384,63 @@ class _EmployeesScreenState extends State<EmployeesScreen> with UIMixin {
|
||||
}
|
||||
|
||||
Widget _buildPopupMenu() {
|
||||
if (!permissionController.hasPermission(Permissions.viewAllEmployees)) {
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
return Obx(() {
|
||||
if (permissionController.isLoading.value ||
|
||||
!permissionController.hasPermission(Permissions.viewAllEmployees)) {
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
|
||||
return PopupMenuButton<String>(
|
||||
icon: Stack(
|
||||
clipBehavior: Clip.none,
|
||||
children: [
|
||||
const Icon(Icons.tune, color: Colors.black),
|
||||
Obx(() => _employeeController.isAllEmployeeSelected.value
|
||||
? Positioned(
|
||||
right: -1,
|
||||
top: -1,
|
||||
child: Container(
|
||||
width: 10,
|
||||
height: 10,
|
||||
decoration: const BoxDecoration(
|
||||
color: Colors.red, shape: BoxShape.circle),
|
||||
return PopupMenuButton<String>(
|
||||
icon: Stack(
|
||||
clipBehavior: Clip.none,
|
||||
children: [
|
||||
const Icon(Icons.tune, color: Colors.black),
|
||||
Obx(() => _employeeController.isAllEmployeeSelected.value
|
||||
? Positioned(
|
||||
right: -1,
|
||||
top: -1,
|
||||
child: Container(
|
||||
width: 10,
|
||||
height: 10,
|
||||
decoration: const BoxDecoration(
|
||||
color: Colors.red, shape: BoxShape.circle),
|
||||
),
|
||||
)
|
||||
: const SizedBox.shrink()),
|
||||
],
|
||||
),
|
||||
onSelected: (value) async {
|
||||
if (value == 'all_employees') {
|
||||
_employeeController.isAllEmployeeSelected.toggle();
|
||||
await _initEmployees();
|
||||
_employeeController.update(['employee_screen_controller']);
|
||||
}
|
||||
},
|
||||
itemBuilder: (_) => [
|
||||
PopupMenuItem<String>(
|
||||
value: 'all_employees',
|
||||
child: Obx(
|
||||
() => Row(
|
||||
children: [
|
||||
Checkbox(
|
||||
value: _employeeController.isAllEmployeeSelected.value,
|
||||
onChanged: (_) => Navigator.pop(context, 'all_employees'),
|
||||
checkColor: Colors.white,
|
||||
activeColor: Colors.blueAccent,
|
||||
side: const BorderSide(color: Colors.black, width: 1.5),
|
||||
fillColor: MaterialStateProperty.resolveWith<Color>(
|
||||
(states) => states.contains(MaterialState.selected)
|
||||
? Colors.blueAccent
|
||||
: Colors.white),
|
||||
),
|
||||
)
|
||||
: const SizedBox.shrink()),
|
||||
],
|
||||
),
|
||||
onSelected: (value) async {
|
||||
if (value == 'all_employees') {
|
||||
_employeeController.isAllEmployeeSelected.toggle();
|
||||
await _initEmployees();
|
||||
_employeeController.update(['employee_screen_controller']);
|
||||
}
|
||||
},
|
||||
itemBuilder: (_) => [
|
||||
PopupMenuItem<String>(
|
||||
value: 'all_employees',
|
||||
child: Obx(
|
||||
() => Row(
|
||||
children: [
|
||||
Checkbox(
|
||||
value: _employeeController.isAllEmployeeSelected.value,
|
||||
onChanged: (_) => Navigator.pop(context, 'all_employees'),
|
||||
checkColor: Colors.white,
|
||||
activeColor: Colors.blueAccent,
|
||||
side: const BorderSide(color: Colors.black, width: 1.5),
|
||||
fillColor: MaterialStateProperty.resolveWith<Color>(
|
||||
(states) => states.contains(MaterialState.selected)
|
||||
? Colors.blueAccent
|
||||
: Colors.white),
|
||||
),
|
||||
const Text('All Employees'),
|
||||
],
|
||||
const Text('All Employees'),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
],
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
Widget _buildEmployeeList() {
|
||||
|
Loading…
x
Reference in New Issue
Block a user