mirror of
https://github.com/SyncrowIOT/web.git
synced 2025-07-09 22:57:21 +00:00
filter
This commit is contained in:
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
@ -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 => [];
|
||||
|
@ -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();
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
@ -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()));
|
||||
// }
|
||||
// }
|
@ -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 => [];
|
||||
}
|
||||
|
@ -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];
|
||||
}
|
||||
|
@ -122,7 +122,7 @@ class _DynamicTableScreenState extends State<DynamicTableScreen>
|
||||
),
|
||||
if (index != 1 &&
|
||||
index != 9 &&
|
||||
index != 7 &&
|
||||
index != 8 &&
|
||||
index != 5)
|
||||
FittedBox(
|
||||
child: IconButton(
|
||||
|
@ -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) {
|
||||
|
Reference in New Issue
Block a user