add_user_dialog

This commit is contained in:
mohammad
2024-12-16 18:19:22 +03:00
parent 879bf99b12
commit a46f69636d
4 changed files with 64 additions and 63 deletions

View File

@ -7,7 +7,6 @@ import 'package:syncrow_web/pages/roles_and_permission/users_page/model/tree_nod
import 'package:syncrow_web/pages/spaces_management/model/community_model.dart';
import 'package:syncrow_web/pages/spaces_management/model/space_model.dart';
import 'package:syncrow_web/services/space_mana_api.dart';
class UsersBloc extends Bloc<UsersEvent, UsersState> {
UsersBloc() : super(UsersInitial()) {
on<GetUsers>(_getUsers);
@ -15,6 +14,7 @@ class UsersBloc extends Bloc<UsersEvent, UsersState> {
on<CheckStepStatus>(isCompleteBasicsFun);
on<LoadCommunityAndSpacesEvent>(_onLoadCommunityAndSpaces);
on<SearchAnode>(searchTreeNode);
on<CheckSpacesStepStatus>(isCompleteSpacesFun);
}
List<RolesUserModel> users = [];
@ -62,7 +62,6 @@ class UsersBloc extends Bloc<UsersEvent, UsersState> {
void _changeUserStatus(ChangeUserStatus event, Emitter<UsersState> emit) {
try {
// Update the user's status
users = users.map((user) {
if (user.id == event.userId) {
return RolesUserModel(
@ -111,21 +110,27 @@ class UsersBloc extends Bloc<UsersEvent, UsersState> {
return isCompleteBasics;
}
isCompleteSpacesFun(CheckStepStatus event, Emitter<UsersState> emit) {
void isCompleteSpacesFun(
CheckSpacesStepStatus event, Emitter<UsersState> emit) {
emit(UsersLoadingState());
isCompleteSpaces = false;
try {
List<String> selectedIds =
getSelectedIds(updatedCommunities);
isCompleteSpaces = selectedIds.isNotEmpty;
} catch (e) {
emit(ErrorState('Error while retrieving selected IDs: $e'));
return;
}
emit(ChangeStatusSteps());
print('isCompleteBasics==$isCompleteSpaces');
return isCompleteSpaces;
}
bool checkRolePermissions() {
return true;
}
bool checkSpaces() {
return true;
}
Future<List<SpaceModel>> _fetchSpacesForCommunity(
String communityUuid) async {
@ -134,83 +139,60 @@ class UsersBloc extends Bloc<UsersEvent, UsersState> {
List<TreeNode> updatedCommunities = [];
List<TreeNode> spacesNodes = [];
_onLoadCommunityAndSpaces(
LoadCommunityAndSpacesEvent event,
Emitter<UsersState> emit,
) async {
emit(UsersLoadingState()); // Emit loading state
LoadCommunityAndSpacesEvent event, Emitter<UsersState> emit) async {
try {
// Fetch the list of communities
emit(UsersLoadingState());
List<CommunityModel> communities =
await CommunitySpaceManagementApi().fetchCommunities();
// Fetch spaces and create TreeNodes for each community
updatedCommunities = await Future.wait(
communities.map((community) async {
// Fetch spaces for the current community
List<SpaceModel> spaces =
await _fetchSpacesForCommunity(community.uuid);
// Recursively build the tree structure
spacesNodes = _buildTreeNodes(spaces);
// Return a TreeNode for the community, with spaces as its children
return TreeNode(
uuid: community.uuid,
title: community.name,
children: spacesNodes,
isChecked: false, // Initial state; can be updated later
isChecked: false,
isHighlighted: false,
isExpanded: true, // Default to expanded for better UX
isExpanded: true,
);
}).toList(),
);
// Emit the final state with the structured tree
emit(ChangeStatusSteps());
return updatedCommunities; // Return the structured data if needed
return updatedCommunities;
} catch (e) {
// Emit error state in case of failure
emit(ErrorState('Error loading communities and spaces: $e'));
}
}
// Helper function to recursively build tree nodes
List<TreeNode> _buildTreeNodes(List<SpaceModel> spaces) {
return spaces.map((space) {
// If the space has children, recursively build nodes for them
List<TreeNode> childNodes =
space.children != null ? _buildTreeNodes(space.children!) : [];
// Create a TreeNode for the current space
space.children != null ? _buildTreeNodes(space.children) : [];
return TreeNode(
uuid: space.uuid!,
title: space.name,
isChecked: false,
isHighlighted: false,
isExpanded: childNodes.isNotEmpty, // Expand if there are children
isExpanded: childNodes.isNotEmpty,
children: childNodes,
);
}).toList();
}
void searchTreeNode(SearchAnode event, Emitter<UsersState> emit) {
emit(UsersLoadingState()); // Emit loading state
// Clear all highlights if the search term is empty
emit(UsersLoadingState());
if (event.searchTerm!.isEmpty) {
_clearHighlights(updatedCommunities);
} else {
// Perform the search and update the highlights
_searchAndHighlightNodes(updatedCommunities, event.searchTerm!);
}
// Emit the updated state after processing all nodes
emit(ChangeStatusSteps());
}
// Helper function to clear all highlights in the tree
void _clearHighlights(List<TreeNode> nodes) {
for (var node in nodes) {
node.isHighlighted = false;
@ -220,25 +202,32 @@ class UsersBloc extends Bloc<UsersEvent, UsersState> {
}
}
// Helper function to search and highlight nodes recursively
bool _searchAndHighlightNodes(List<TreeNode> nodes, String searchTerm) {
bool anyMatch = false;
for (var node in nodes) {
// Check if this node matches the search term
bool isMatch =
node.title.toLowerCase().contains(searchTerm.toLowerCase());
// Recursively check children for matches
bool childMatch = _searchAndHighlightNodes(node.children, searchTerm);
// Highlight this node if it matches or any of its children match
node.isHighlighted = isMatch || childMatch;
// Update if any matches were found in this branch
anyMatch = anyMatch || node.isHighlighted;
}
return anyMatch;
}
List<String> selectedIds = [];
List<String> getSelectedIds(List<TreeNode> nodes) {
List<String> selectedIds = [];
for (var node in nodes) {
if (node.isChecked) {
selectedIds.add(node.uuid);
}
if (node.children.isNotEmpty) {
selectedIds.addAll(getSelectedIds(node.children));
}
}
return selectedIds;
}
}

View File

@ -10,6 +10,11 @@ class GetUsers extends UsersEvent {
@override
List<Object?> get props => [];
}
class CheckSpacesStepStatus extends UsersEvent {
const CheckSpacesStepStatus();
@override
List<Object?> get props => [];
}
class LoadCommunityAndSpacesEvent extends UsersEvent {
const LoadCommunityAndSpacesEvent();
@ -49,3 +54,9 @@ class SearchAnode extends UsersEvent {
@override
List<Object?> get props => [nodes, searchTerm];
}
class SelecteId extends UsersEvent {
List<TreeNode>? nodes;
SelecteId({this.nodes,});
@override
List<Object?> get props => [nodes];
}

View File

@ -23,7 +23,8 @@ class _AddNewUserDialogState extends State<AddNewUserDialog> {
@override
Widget build(BuildContext context) {
return BlocProvider(
create: (BuildContext context) => UsersBloc()..add(LoadCommunityAndSpacesEvent()),
create: (BuildContext context) =>
UsersBloc()..add(LoadCommunityAndSpacesEvent()),
child: BlocConsumer<UsersBloc, UsersState>(
listener: (context, state) {},
builder: (context, state) {
@ -162,6 +163,8 @@ class _AddNewUserDialogState extends State<AddNewUserDialog> {
? Assets.currentProcessIcon
: bloc.isCompleteSpaces == false
? Assets.wrongProcessIcon
: bloc.isCompleteSpaces == true
? Assets.completeProcessIcon
: Assets.uncomplete_ProcessIcon,
width: 25,
height: 25,
@ -263,6 +266,7 @@ class _AddNewUserDialogState extends State<AddNewUserDialog> {
onTap: () {
setState(() {
currentStep = step;
bloc.add(const CheckSpacesStepStatus());
});
},
child: Column(

View File

@ -125,6 +125,7 @@ class SpacesAccessView extends StatelessWidget {
}
// ignore: must_be_immutable
class TreeView extends StatefulWidget {
UsersBloc? bloc;
TreeView({super.key, this.bloc});
@ -155,6 +156,8 @@ class _TreeViewState extends State<TreeView> {
node.isChecked = !node.isChecked;
_updateChildrenCheckStatus(node, node.isChecked);
_updateParentCheckStatus(node);
// widget.bloc!.add(
// SelecteId(nodes: widget.bloc!.updatedCommunities));
});
},
child: Image.asset(
@ -210,7 +213,6 @@ class _TreeViewState extends State<TreeView> {
);
}
// Determine the appropriate image based on the check state
String _getCheckBoxImage(TreeNode node) {
if (node.children.isEmpty) {
return node.isChecked ? Assets.CheckBoxChecked : Assets.emptyBox;
@ -224,7 +226,6 @@ class _TreeViewState extends State<TreeView> {
}
}
// Helper to determine if all children are checked
bool _areAllChildrenChecked(TreeNode node) {
return node.children.isNotEmpty &&
node.children.every((child) =>
@ -232,7 +233,6 @@ class _TreeViewState extends State<TreeView> {
(child.children.isEmpty || _areAllChildrenChecked(child)));
}
// Helper to determine if some children are checked
bool _areSomeChildrenChecked(TreeNode node) {
return node.children.isNotEmpty &&
node.children.any((child) =>
@ -240,7 +240,6 @@ class _TreeViewState extends State<TreeView> {
(child.children.isNotEmpty && _areSomeChildrenChecked(child)));
}
// Update the checkbox state for all children
void _updateChildrenCheckStatus(TreeNode node, bool isChecked) {
for (var child in node.children) {
child.isChecked = isChecked;
@ -248,18 +247,16 @@ class _TreeViewState extends State<TreeView> {
}
}
// Update the checkbox state for parent nodes
void _updateParentCheckStatus(TreeNode node) {
TreeNode? parent = _findParent(widget.bloc!.updatedCommunities, node);
if (parent != null) {
setState(() {
parent.isChecked = _areAllChildrenChecked(parent);
_updateParentCheckStatus(parent); // Recursively update ancestors
_updateParentCheckStatus(parent);
});
}
}
// Helper to find a node's parent
TreeNode? _findParent(List<TreeNode> nodes, TreeNode target) {
for (var node in nodes) {
if (node.children.contains(target)) {