This commit is contained in:
mohammad
2025-01-06 14:20:57 +03:00
parent 3876909bea
commit fe8f8160ec
8 changed files with 580 additions and 413 deletions

View File

@ -30,8 +30,8 @@ class UsersBloc extends Bloc<UsersEvent, UsersState> {
on<ToggleNodeExpansion>(_onToggleNodeExpansion);
on<ToggleNodeCheck>(_onToggleNodeCheck);
on<EditInviteUsers>(_editInvitUser);
}
void _validateBasicsStep(ValidateBasicsStep event, Emitter<UsersState> emit) {
if (formKey.currentState?.validate() ?? false) {
emit(const BasicsStepValidState());
@ -381,7 +381,7 @@ class UsersBloc extends Bloc<UsersEvent, UsersState> {
// Create a list of UUIDs to mark
final uuidsToMark = res.spaces.map((space) => space.uuid).toList();
// Print all IDs and mark nodes in updatedCommunities
print('Printing and marking nodes in updatedCommunities:');
debugPrint('Printing and marking nodes in updatedCommunities:');
_printAndMarkNodes(updatedCommunities, uuidsToMark);
} else {
print('updatedCommunities is empty!');
@ -391,34 +391,27 @@ class UsersBloc extends Bloc<UsersEvent, UsersState> {
element.type ==
res.roleType.toString().toLowerCase().replaceAll("_", " "))
.uuid;
print('Role ID: $roleId');
debugPrint('Role ID: $roleId');
roleSelected = roleId;
add(PermissionEvent(roleUuid: roleSelected));
emit(ChangeStatusSteps());
} else {
// emit(UsersErrorState("User not found"));
}
} else {
// emit(UsersErrorState("Invalid user ID"));
}
} else {}
} else {}
} catch (e) {
print("Failed to fetch user data: $e");
// emit(UsersErrorState("Failed to fetch user data: $e"));
}
}
/// Recursively print all the node IDs, including nested children.
/// Recursively print all node IDs and mark nodes as `isChecked` if their UUID exists in the list.
void _printAndMarkNodes(List<TreeNode> nodes, List<String> uuidsToMark,
[int level = 0]) {
for (final node in nodes) {
// Check if the current node's UUID exists in the list of UUIDs to mark.
if (uuidsToMark.contains(node.uuid)) {
node.isChecked = true; // Mark the node as checked.
print(
node.isChecked = true;
debugPrint(
'${' ' * level}MATCH FOUND: Node ID: ${node.uuid}, Title: ${node.title} is marked as checked.');
} else {
print('${' ' * level}Node ID: ${node.uuid}, Title: ${node.title}');
debugPrint(
'${' ' * level}Node ID: ${node.uuid}, Title: ${node.title}');
}
if (node.children.isNotEmpty) {
_printAndMarkNodes(node.children, uuidsToMark, level + 1);
@ -453,8 +446,6 @@ class UsersBloc extends Bloc<UsersEvent, UsersState> {
emit(ChangeStatusSteps());
}
// Existing methods that remain in the BLoC:
void _updateChildrenCheckStatus(TreeNode node, bool isChecked) {
for (var child in node.children) {
child.isChecked = isChecked;
@ -477,7 +468,6 @@ class UsersBloc extends Bloc<UsersEvent, UsersState> {
(child.children.isEmpty || _areAllChildrenChecked(child)));
}
// Private helper method to find the parent of a given node.
TreeNode? _findParent(List<TreeNode> nodes, TreeNode target) {
for (var node in nodes) {
if (node.children.contains(target)) {
@ -490,7 +480,4 @@ class UsersBloc extends Bloc<UsersEvent, UsersState> {
}
return null;
}
}

View File

@ -129,8 +129,6 @@ class UpdateNodeCheckStatus extends UsersEvent {
@override
List<Object?> get props => [node];
}
// Define new events
class ToggleNodeHighlightEvent extends UsersEvent {
final TreeNode node;
@ -161,14 +159,9 @@ class ToggleNodeCheckEvent extends UsersEvent {
@override
List<Object?> get props => [];
}
// users_event.dart
// 1. Extend UsersEvent
class ToggleNodeCheck extends UsersEvent {
final TreeNode node;
// 2. Add a constructor that takes the node to toggle
ToggleNodeCheck(this.node);
@override
List<Object?> get props => [];

View File

@ -1,6 +1,9 @@
import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
import 'package:syncrow_web/utils/color_manager.dart';
import 'package:syncrow_web/utils/constants/assets.dart';
import 'package:syncrow_web/utils/extension/build_context_x.dart';
import 'package:syncrow_web/utils/style.dart';
Future<void> showPopUpFilterMenu({
required BuildContext context,
@ -8,20 +11,18 @@ Future<void> showPopUpFilterMenu({
Function()? onSortZtoA,
Function()? cancelButton,
required Map<String, bool> checkboxStates,
required RelativeRect position,
// Function(String)? onTextFieldChanged,
Function()? onOkPressed,
List<String>? list,
}) async {
final RenderBox overlay =
Overlay.of(context).context.findRenderObject() as RenderBox;
await showMenu(
context: context,
position: RelativeRect.fromLTRB(
overlay.size.width / 4,
240,
overlay.size.width / 4,
0,
),
position:position,
color: ColorsManager.whiteColors,
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(10)),
@ -55,28 +56,69 @@ Future<void> showPopUpFilterMenu({
),
const PopupMenuDivider(),
const PopupMenuItem(
child: Text(
"Filter by Status",
style: TextStyle(fontWeight: FontWeight.bold),
),
),
child: Text(
"Filter by Status",
style: TextStyle(fontWeight: FontWeight.bold),
)
// Container(
// decoration: containerDecoration.copyWith(
// boxShadow: [],
// borderRadius: const BorderRadius.only(
// topLeft: Radius.circular(10), topRight: Radius.circular(10))),
// child: Padding(
// padding: const EdgeInsets.all(8.0),
// child: TextFormField(
// onChanged: onTextFieldChanged,
// style: const TextStyle(color: Colors.black),
// decoration: textBoxDecoration(radios: 15)!.copyWith(
// fillColor: ColorsManager.whiteColors,
// errorStyle: const TextStyle(height: 0),
// hintStyle: context.textTheme.titleSmall?.copyWith(
// color: Colors.grey,
// fontSize: 12,
// ),
// hintText: 'Search',
// suffixIcon: SizedBox(
// child: SvgPicture.asset(
// Assets.searchIconUser,
// fit: BoxFit.none,
// ),
// ),
// ),
// // "Filter by Status",
// // style: TextStyle(fontWeight: FontWeight.bold),
// ),
// ),
// ),
),
PopupMenuItem(
child: SizedBox(
child: Container(
decoration: containerDecoration.copyWith(
boxShadow: [],
borderRadius: const BorderRadius.only(
bottomLeft: Radius.circular(10),
bottomRight: Radius.circular(10))),
padding: const EdgeInsets.all(10),
height: 200,
width: 400,
child: ListView.builder(
itemCount: list?.length ?? 0,
itemBuilder: (context, index) {
final item = list![index];
return CheckboxListTile(
title: Text(item),
value: checkboxStates[item],
onChanged: (bool? newValue) {
checkboxStates[item] = newValue ?? false;
(context as Element).markNeedsBuild();
},
);
},
child: Container(
padding: const EdgeInsets.all(10),
color: Colors.white,
child: ListView.builder(
itemCount: list?.length ?? 0,
itemBuilder: (context, index) {
final item = list![index];
return CheckboxListTile(
dense: true,
title: Text(item),
value: checkboxStates[item],
onChanged: (bool? newValue) {
checkboxStates[item] = newValue ?? false;
(context as Element).markNeedsBuild();
},
);
},
),
),
),
),

View File

@ -19,8 +19,9 @@ class UserTableBloc extends Bloc<UserTableEvent, UserTableState> {
on<FilterUsersByRoleEvent>(_filterUsersByRole);
on<FilterUsersByJobEvent>(_filterUsersByJobTitle);
on<FilterUsersByCreatedEvent>(_filterUsersByCreated);
on<FilterUsersByDeActevateEvent>(_filterUserActevate);
on<FilterUsersByDeActevateEvent>(_filterUserStatus);
on<DeleteUserEvent>(_deleteUser);
on<FilterClearEvent>(_filterClear);
}
int itemsPerPage = 10;
int currentPage = 1;
@ -31,7 +32,7 @@ class UserTableBloc extends Bloc<UserTableEvent, UserTableState> {
List<String> roleTypes = [];
List<String> jobTitle = [];
List<String> createdBy = [];
List<String> deActivate = [];
List<String> status = ['active', 'invited', 'disabled'];
Future<void> _getUsers(GetUsers event, Emitter<UserTableState> emit) async {
emit(UsersLoadingState());
@ -39,8 +40,14 @@ class UserTableBloc extends Bloc<UserTableEvent, UserTableState> {
roleTypes.clear();
jobTitle.clear();
createdBy.clear();
deActivate.clear();
// deActivate.clear();
users = await UserPermissionApi().fetchUsers();
users.sort((a, b) {
final dateA = _parseDateTime(a.createdDate);
final dateB = _parseDateTime(b.createdDate);
return dateB.compareTo(dateA);
});
for (var user in users) {
roleTypes.add(user.roleType.toString());
}
@ -50,20 +57,14 @@ class UserTableBloc extends Bloc<UserTableEvent, UserTableState> {
for (var user in users) {
createdBy.add(user.invitedBy.toString());
}
for (var user in users) {
deActivate.add(user.status.toString());
}
// for (var user in users) {
// deActivate.add(user.status.toString());
// }
initialUsers = List.from(users);
roleTypes = roleTypes.toSet().toList();
jobTitle = jobTitle.toSet().toList();
createdBy = createdBy.toSet().toList();
deActivate = deActivate.toSet().toList();
users.sort((a, b) {
final dateA = _parseDateTime(a.createdDate);
final dateB = _parseDateTime(b.createdDate);
return dateB.compareTo(dateA);
});
initialUsers = List.from(users);
// deActivate = deActivate.toSet().toList();
_handlePageChange(ChangePage(1), emit);
emit(UsersLoadedState(users: users));
} catch (e) {
@ -127,7 +128,7 @@ class UserTableBloc extends Bloc<UserTableEvent, UserTableState> {
if (currentSortOrder == "Asc") {
emit(UsersLoadingState());
currentSortOrder = "";
users = List.from(initialUsers);
users = List.from(users);
emit(UsersLoadedState(users: users));
} else {
emit(UsersLoadingState());
@ -248,39 +249,83 @@ class UserTableBloc extends Bloc<UserTableEvent, UserTableState> {
emit(UsersLoadedState(users: paginatedUsers));
}
Set<String> selectedRoles = {};
Set<String> selectedJobTitles = {};
Set<String> selectedCreatedBy = {};
Set<String> selectedStatuses = {};
void _filterUsersByRole(
FilterUsersByRoleEvent event, Emitter<UserTableState> emit) {
emit(UsersLoadingState());
selectedRoles = event.selectedRoles.toSet();
final filteredUsers = initialUsers.where((user) {
return event.selectedRoles.contains(user.roleType);
if (selectedRoles.isEmpty) return true;
return selectedRoles.contains(user.roleType);
}).toList();
emit(UsersLoadedState(users: filteredUsers));
}
void _filterUsersByJobTitle(
FilterUsersByJobEvent event, Emitter<UserTableState> emit) {
emit(UsersLoadingState());
final filteredUsers = users.where((user) {
return event.selectedJob.contains(user.jobTitle);
selectedJobTitles = event.selectedJob.toSet();
final filteredUsers = initialUsers.where((user) {
if (selectedJobTitles.isEmpty) return true;
return selectedJobTitles.contains(user.jobTitle);
}).toList();
emit(UsersLoadedState(users: filteredUsers));
}
void _filterUsersByCreated(
FilterUsersByCreatedEvent event, Emitter<UserTableState> emit) {
emit(UsersLoadingState());
selectedCreatedBy = event.selectedCreatedBy.toSet();
final filteredUsers = initialUsers.where((user) {
return event.selectedCreatedBy.contains(user.invitedBy);
if (selectedCreatedBy.isEmpty) return true;
return selectedCreatedBy.contains(user.invitedBy);
}).toList();
emit(UsersLoadedState(users: filteredUsers));
}
void _filterUserActevate(
void _filterUserStatus(
FilterUsersByDeActevateEvent event, Emitter<UserTableState> emit) {
emit(UsersLoadingState());
selectedStatuses = event.selectedActivate.toSet();
final filteredUsers = initialUsers.where((user) {
return event.selectedActivate.contains(user.status);
if (selectedStatuses.isEmpty) return true;
return selectedStatuses.contains(user.status);
}).toList();
emit(UsersLoadedState(users: filteredUsers));
}
void _resetAllFilters(Emitter<UserTableState> emit) {
selectedRoles.clear();
selectedJobTitles.clear();
selectedCreatedBy.clear();
selectedStatuses.clear();
emit(UsersLoadedState(users: initialUsers));
}
void _filterClear(FilterClearEvent event, Emitter<UserTableState> emit) {
selectedRoles.clear();
selectedJobTitles.clear();
selectedCreatedBy.clear();
selectedStatuses.clear();
emit(UsersLoadedState(users: initialUsers));
}
}
// void _filterOptions(FilterOptionsEvent event, Emitter<UserTableState> emit) {
// try {
// final query = event.query.toLowerCase();
// final filteredOptions = event.fullOptions
// .where((option) => option.toLowerCase().contains(query))
// .toList();
// emit(FilterOptionsState(filteredOptions));
// } catch (e) {
// emit(ErrorState(e.toString()));
// }
// }

View File

@ -119,3 +119,19 @@ class FilterUsersByDeActevateEvent extends UserTableEvent {
@override
List<Object?> get props => [selectedActivate];
}
class FilterOptionsEvent extends UserTableEvent {
final String query;
final List<String> fullOptions;
FilterOptionsEvent({required this.query, required this.fullOptions});
@override
List<Object?> get props => [query, fullOptions];
}
class FilterClearEvent extends UserTableEvent {
FilterClearEvent();
@override
List<Object?> get props => [];
}

View File

@ -80,3 +80,12 @@ final class ChangeTapStatus extends UserTableState {
@override
List<Object> get props => [select];
}
class FilterOptionsState extends UserTableState {
final List<String> filteredOptions;
FilterOptionsState(this.filteredOptions);
@override
List<Object> get props => [filteredOptions];
}

View File

@ -122,7 +122,7 @@ class _DynamicTableScreenState extends State<DynamicTableScreen>
),
if (index != 1 &&
index != 9 &&
index != 7 &&
index != 8 &&
index != 5)
FittedBox(
child: IconButton(

View File

@ -110,350 +110,425 @@ class UsersPage extends StatelessWidget {
if (state is UsersLoadingState) {
_blocRole.add(ChangePage(_blocRole.currentPage));
return const Center(child: CircularProgressIndicator());
} else if (state is UsersLoadedState) {
return Padding(
padding: const EdgeInsets.all(20),
child: ListView(
shrinkWrap: true,
children: [
Row(
children: [
Container(
decoration: containerDecoration.copyWith(
borderRadius: const BorderRadius.all(
Radius.circular(20),
),
),
width: screenSize.width * 0.4,
child: TextFormField(
controller: searchController,
onChanged: (value) {
context.read<UserTableBloc>().add(SearchUsers(value));
},
style: const TextStyle(color: Colors.black),
decoration: textBoxDecoration(radios: 15)!.copyWith(
fillColor: ColorsManager.whiteColors,
errorStyle: const TextStyle(height: 0),
hintStyle: context.textTheme.titleSmall?.copyWith(
color: Colors.grey,
fontSize: 12,
),
hintText: 'Search',
suffixIcon: SizedBox(
child: SvgPicture.asset(
Assets.searchIconUser,
fit: BoxFit.none,
),
),
),
),
),
const SizedBox(width: 20),
InkWell(
onTap: () {
showDialog(
context: context,
barrierDismissible: false,
builder: (BuildContext context) {
return const AddNewUserDialog();
},
).then((v) {
if (v != null) {
_blocRole.add(const GetUsers());
}
});
},
child: Container(
decoration: containerWhiteDecoration,
width: screenSize.width * 0.18,
height: 50,
child: const Center(
child: Text(
'Add New User',
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w700,
color: ColorsManager.blueColor,
),
),
),
),
),
],
),
const SizedBox(height: 25),
DynamicTableScreen(
onFilter: (columnIndex) {
if (columnIndex == 0) {
showNameMenu(
context: context,
isSelected: _blocRole.currentSortOrder,
aToZTap: () {
context
.read<UserTableBloc>()
.add(const SortUsersByNameAsc());
},
zToaTap: () {
context
.read<UserTableBloc>()
.add(const SortUsersByNameDesc());
},
);
}
if (columnIndex == 2) {
final Map<String, bool> checkboxStates = {
for (var item in _blocRole.jobTitle)
item: false, // Initialize with false
};
showPopUpFilterMenu(
list: _blocRole.jobTitle,
context: context,
checkboxStates: checkboxStates,
onOkPressed: () {
final selectedItems = checkboxStates.entries
.where((entry) => entry.value)
.map((entry) => entry.key)
.toList();
Navigator.of(context).pop();
_blocRole.add(FilterUsersByJobEvent(selectedItems));
},
onSortAtoZ: () {
context
.read<UserTableBloc>()
.add(const SortUsersByNameAsc());
},
onSortZtoA: () {
context
.read<UserTableBloc>()
.add(const SortUsersByNameDesc());
},
);
}
if (columnIndex == 3) {
final Map<String, bool> checkboxStates = {
for (var item in _blocRole.roleTypes)
item: false, // Initialize with false
};
showPopUpFilterMenu(
list: _blocRole.roleTypes,
context: context,
checkboxStates: checkboxStates,
onOkPressed: () {
final selectedItems = checkboxStates.entries
.where((entry) => entry.value)
.map((entry) => entry.key)
.toList();
Navigator.of(context).pop();
_blocRole.add(FilterUsersByRoleEvent(selectedItems));
},
onSortAtoZ: () {
context
.read<UserTableBloc>()
.add(const SortUsersByNameAsc());
},
onSortZtoA: () {
context
.read<UserTableBloc>()
.add(const SortUsersByNameDesc());
},
);
}
if (columnIndex == 4) {
showDateFilterMenu(
context: context,
isSelected: _blocRole.currentSortOrderDate,
aToZTap: () {
context
.read<UserTableBloc>()
.add(const DateNewestToOldestEvent());
},
zToaTap: () {
context
.read<UserTableBloc>()
.add(const DateOldestToNewestEvent());
},
);
}
if (columnIndex == 6) {
final Map<String, bool> checkboxStates = {
for (var item in _blocRole.createdBy)
item: false, // Initialize with false
};
showPopUpFilterMenu(
list: _blocRole.createdBy,
context: context,
checkboxStates: checkboxStates,
onOkPressed: () {
final selectedItems = checkboxStates.entries
.where((entry) => entry.value)
.map((entry) => entry.key)
.toList();
Navigator.of(context).pop();
_blocRole
.add(FilterUsersByCreatedEvent(selectedItems));
},
onSortAtoZ: () {
context
.read<UserTableBloc>()
.add(const SortUsersByNameAsc());
},
onSortZtoA: () {
context
.read<UserTableBloc>()
.add(const SortUsersByNameDesc());
},
);
}
if (columnIndex == 8) {
showDeActivateFilterMenu(
context: context,
isSelected: _blocRole.currentSortOrderDate,
aToZTap: () {
context
.read<UserTableBloc>()
.add(const DateNewestToOldestEvent());
},
zToaTap: () {
context
.read<UserTableBloc>()
.add(const DateOldestToNewestEvent());
},
);
}
},
titles: const [
"Full Name",
"Email Address",
"Job Title",
"Role",
"Creation Date",
"Creation Time",
"Created By",
"Status",
"De/Activate",
"Action"
],
rows: state.users.map((user) {
return [
Text('${user.firstName} ${user.lastName}'),
Text(user.email ?? ''),
Text(user.jobTitle ?? ''),
Text(user.roleType ?? ''),
Text(user.createdDate ?? ''),
Text(user.createdTime ?? ''),
Text(user.invitedBy),
changeIconStatus(
status:
user.isEnabled == false ? 'disabled' : user.status,
userId: user.uuid,
onTap: user.status != "invited"
? () {
final newStatus = user.status == 'active'
? 'disabled'
: user.status == 'disabled'
? 'invited'
: 'active';
context.read<UserTableBloc>().add(
ChangeUserStatus(
userId: user.uuid,
newStatus: user.isEnabled == false
? 'disabled'
: user.status));
}
: null,
),
status(
status:
user.isEnabled == false ? 'disabled' : user.status,
),
Row(
children: [
// actionButton(
// title: "Activity Log",
// onTap: () {},
// ),
actionButton(
title: "Edit",
onTap: () {
showDialog(
context: context,
barrierDismissible: false,
builder: (BuildContext context) {
return EditUserDialog(userId: user.uuid);
},
).then((v) {
if (v != null) {
if (v != null) {
_blocRole.add(const GetUsers());
}
}
});
},
),
actionButton(
title: "Delete",
onTap: () {
showDialog(
context: context,
barrierDismissible: false,
builder: (BuildContext context) {
return DeleteUserDialog(
onTapDelete: () {
_blocRole.add(
DeleteUserEvent(user.uuid, context));
},
);
},
).then((v) {
if (v != null) {
if (v != null) {
_blocRole.add(const GetUsers());
}
}
});
},
),
],
),
];
}).toList(),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
child: Align(
alignment: Alignment.topCenter,
child: ListView(
shrinkWrap: true,
children: [
Row(
children: [
Container(
width: 500,
child: NumberPagination(
buttonRadius: 10,
selectedButtonColor: ColorsManager.secondaryColor,
buttonUnSelectedBorderColor: ColorsManager.grayBorder,
lastPageIcon:
const Icon(Icons.keyboard_double_arrow_right),
firstPageIcon:
const Icon(Icons.keyboard_double_arrow_left),
totalPages:
(_blocRole.users.length / _blocRole.itemsPerPage)
.ceil(),
currentPage: _blocRole.currentPage,
onPageChanged: (int pageNumber) {
_blocRole.currentPage = pageNumber;
decoration: containerDecoration.copyWith(
borderRadius: const BorderRadius.all(
Radius.circular(20),
),
),
width: screenSize.width * 0.4,
child: TextFormField(
controller: searchController,
onChanged: (value) {
context
.read<UserTableBloc>()
.add(ChangePage(pageNumber));
.add(SearchUsers(value));
},
style: const TextStyle(color: Colors.black),
decoration: textBoxDecoration(radios: 15)!.copyWith(
fillColor: ColorsManager.whiteColors,
errorStyle: const TextStyle(height: 0),
hintStyle: context.textTheme.titleSmall?.copyWith(
color: Colors.grey,
fontSize: 12,
),
hintText: 'Search',
suffixIcon: SizedBox(
child: SvgPicture.asset(
Assets.searchIconUser,
fit: BoxFit.none,
),
),
),
),
),
const SizedBox(width: 20),
InkWell(
onTap: () {
showDialog(
context: context,
barrierDismissible: false,
builder: (BuildContext context) {
return const AddNewUserDialog();
},
).then((v) {
if (v != null) {
_blocRole.add(const GetUsers());
}
});
},
child: Container(
decoration: containerWhiteDecoration,
width: screenSize.width * 0.18,
height: 50,
child: const Center(
child: Text(
'Add New User',
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w700,
color: ColorsManager.blueColor,
),
),
),
),
),
],
),
),
],
const SizedBox(height: 25),
DynamicTableScreen(
onFilter: (columnIndex) {
_blocRole.add(FilterClearEvent());
if (columnIndex == 0) {
showNameMenu(
context: context,
isSelected: _blocRole.currentSortOrder,
aToZTap: () {
context
.read<UserTableBloc>()
.add(const SortUsersByNameAsc());
},
zToaTap: () {
context
.read<UserTableBloc>()
.add(const SortUsersByNameDesc());
},
);
}
if (columnIndex == 2) {
final Map<String, bool> checkboxStates = {
for (var item in _blocRole.jobTitle)
item: false, // Initialize with false
};
final RenderBox overlay = Overlay.of(context)
.context
.findRenderObject() as RenderBox;
showPopUpFilterMenu(
position: RelativeRect.fromLTRB(
overlay.size.width / 4,
240,
overlay.size.width / 4,
0,
),
list: _blocRole.jobTitle,
context: context,
checkboxStates: checkboxStates,
onOkPressed: () {
final selectedItems = checkboxStates.entries
.where((entry) => entry.value)
.map((entry) => entry.key)
.toList();
Navigator.of(context).pop();
_blocRole.add(FilterUsersByJobEvent(selectedItems));
},
onSortAtoZ: () {
context
.read<UserTableBloc>()
.add(const SortUsersByNameAsc());
},
onSortZtoA: () {
context
.read<UserTableBloc>()
.add(const SortUsersByNameDesc());
},
);
}
if (columnIndex == 3) {
final Map<String, bool> checkboxStates = {
for (var item in _blocRole.roleTypes)
item: _blocRole.selectedRoles.contains(item),
};
final RenderBox overlay = Overlay.of(context)
.context
.findRenderObject() as RenderBox;
showPopUpFilterMenu(
position: RelativeRect.fromLTRB(
overlay.size.width / 4,
240,
overlay.size.width / 4,
0,
),
list: _blocRole.roleTypes,
context: context,
checkboxStates: checkboxStates,
onOkPressed: () {
final selectedItems = checkboxStates.entries
.where((entry) => entry.value)
.map((entry) => entry.key)
.toList();
Navigator.of(context).pop();
context
.read<UserTableBloc>()
.add(FilterUsersByRoleEvent(selectedItems));
},
onSortAtoZ: () {
context
.read<UserTableBloc>()
.add(const SortUsersByNameAsc());
},
onSortZtoA: () {
context
.read<UserTableBloc>()
.add(const SortUsersByNameDesc());
},
);
}
if (columnIndex == 4) {
showDateFilterMenu(
context: context,
isSelected: _blocRole.currentSortOrderDate,
aToZTap: () {
context
.read<UserTableBloc>()
.add(const DateNewestToOldestEvent());
},
zToaTap: () {
context
.read<UserTableBloc>()
.add(const DateOldestToNewestEvent());
},
);
}
if (columnIndex == 6) {
final Map<String, bool> checkboxStates = {
for (var item in _blocRole.createdBy)
item: _blocRole.selectedCreatedBy.contains(item),
};
final RenderBox overlay = Overlay.of(context)
.context
.findRenderObject() as RenderBox;
showPopUpFilterMenu(
position: RelativeRect.fromLTRB(
overlay.size.width / 1,
240,
overlay.size.width / 4,
0,
),
list: _blocRole.createdBy,
context: context,
checkboxStates: checkboxStates,
onOkPressed: () {
final selectedItems = checkboxStates.entries
.where((entry) => entry.value)
.map((entry) => entry.key)
.toList();
Navigator.of(context).pop();
_blocRole
.add(FilterUsersByCreatedEvent(selectedItems));
},
onSortAtoZ: () {
context
.read<UserTableBloc>()
.add(const SortUsersByNameAsc());
},
onSortZtoA: () {
context
.read<UserTableBloc>()
.add(const SortUsersByNameDesc());
},
);
}
if (columnIndex == 7) {
final Map<String, bool> checkboxStates = {
for (var item in _blocRole.status)
item: _blocRole.selectedCreatedBy.contains(item),
};
final RenderBox overlay = Overlay.of(context)
.context
.findRenderObject() as RenderBox;
showPopUpFilterMenu(
position: RelativeRect.fromLTRB(
overlay.size.width / 0,
240,
overlay.size.width / 4,
0,
),
list: _blocRole.status,
context: context,
checkboxStates: checkboxStates,
onOkPressed: () {
final selectedItems = checkboxStates.entries
.where((entry) => entry.value)
.map((entry) => entry.key)
.toList();
Navigator.of(context).pop();
_blocRole
.add(FilterUsersByCreatedEvent(selectedItems));
},
onSortAtoZ: () {
context
.read<UserTableBloc>()
.add(const SortUsersByNameAsc());
},
onSortZtoA: () {
context
.read<UserTableBloc>()
.add(const SortUsersByNameDesc());
},
);
}
if (columnIndex == 8) {
showDeActivateFilterMenu(
context: context,
isSelected: _blocRole.currentSortOrderDate,
aToZTap: () {
context
.read<UserTableBloc>()
.add(const DateNewestToOldestEvent());
},
zToaTap: () {
context
.read<UserTableBloc>()
.add(const DateOldestToNewestEvent());
},
);
}
},
titles: const [
"Full Name",
"Email Address",
"Job Title",
"Role",
"Creation Date",
"Creation Time",
"Created By",
"Status",
"De/Activate",
"Action"
],
rows: state.users.map((user) {
return [
Text('${user.firstName} ${user.lastName}'),
Text(user.email ?? ''),
Text(user.jobTitle ?? ''),
Text(user.roleType ?? ''),
Text(user.createdDate ?? ''),
Text(user.createdTime ?? ''),
Text(user.invitedBy),
status(
status: user.isEnabled == false
? 'disabled'
: user.status,
),
changeIconStatus(
status: user.isEnabled == false
? 'disabled'
: user.status,
userId: user.uuid,
onTap: user.status != "invited"
? () {
final newStatus = user.status == 'active'
? 'disabled'
: user.status == 'disabled'
? 'invited'
: 'active';
context.read<UserTableBloc>().add(
ChangeUserStatus(
userId: user.uuid,
newStatus: user.isEnabled == false
? 'disabled'
: user.status));
}
: null,
),
Row(
children: [
// actionButton(
// title: "Activity Log",
// onTap: () {},
// ),
actionButton(
title: "Edit",
onTap: () {
showDialog(
context: context,
barrierDismissible: false,
builder: (BuildContext context) {
return EditUserDialog(userId: user.uuid);
},
).then((v) {
if (v != null) {
if (v != null) {
_blocRole.add(const GetUsers());
}
}
});
},
),
actionButton(
title: "Delete",
onTap: () {
showDialog(
context: context,
barrierDismissible: false,
builder: (BuildContext context) {
return DeleteUserDialog(
onTapDelete: () {
_blocRole.add(DeleteUserEvent(
user.uuid, context));
},
);
},
).then((v) {
if (v != null) {
if (v != null) {
_blocRole.add(const GetUsers());
}
}
});
},
),
],
),
];
}).toList(),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Container(
width: 500,
child: NumberPagination(
buttonRadius: 10,
selectedButtonColor: ColorsManager.secondaryColor,
buttonUnSelectedBorderColor:
ColorsManager.grayBorder,
lastPageIcon:
const Icon(Icons.keyboard_double_arrow_right),
firstPageIcon:
const Icon(Icons.keyboard_double_arrow_left),
totalPages: (_blocRole.users.length /
_blocRole.itemsPerPage)
.ceil(),
currentPage: _blocRole.currentPage,
onPageChanged: (int pageNumber) {
_blocRole.currentPage = pageNumber;
context
.read<UserTableBloc>()
.add(ChangePage(pageNumber));
},
),
),
],
),
),
],
),
),
);
} else if (state is ErrorState) {