diff --git a/lib/pages/roles_and_permission/users_page/bloc/users_bloc.dart b/lib/pages/roles_and_permission/users_page/bloc/users_bloc.dart index 0d153804..72c85bad 100644 --- a/lib/pages/roles_and_permission/users_page/bloc/users_bloc.dart +++ b/lib/pages/roles_and_permission/users_page/bloc/users_bloc.dart @@ -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 { UsersBloc() : super(UsersInitial()) { on(_getUsers); @@ -15,6 +14,7 @@ class UsersBloc extends Bloc { on(isCompleteBasicsFun); on(_onLoadCommunityAndSpaces); on(searchTreeNode); + on(isCompleteSpacesFun); } List users = []; @@ -62,7 +62,6 @@ class UsersBloc extends Bloc { void _changeUserStatus(ChangeUserStatus event, Emitter 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 { return isCompleteBasics; } - isCompleteSpacesFun(CheckStepStatus event, Emitter emit) { + void isCompleteSpacesFun( + CheckSpacesStepStatus event, Emitter emit) { emit(UsersLoadingState()); - isCompleteSpaces = false; + + try { + List 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> _fetchSpacesForCommunity( String communityUuid) async { @@ -134,83 +139,60 @@ class UsersBloc extends Bloc { List updatedCommunities = []; List spacesNodes = []; + _onLoadCommunityAndSpaces( - LoadCommunityAndSpacesEvent event, - Emitter emit, - ) async { - emit(UsersLoadingState()); // Emit loading state + LoadCommunityAndSpacesEvent event, Emitter emit) async { try { - // Fetch the list of communities + emit(UsersLoadingState()); List 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 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 _buildTreeNodes(List spaces) { return spaces.map((space) { - // If the space has children, recursively build nodes for them List 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 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 nodes) { for (var node in nodes) { node.isHighlighted = false; @@ -220,25 +202,32 @@ class UsersBloc extends Bloc { } } -// Helper function to search and highlight nodes recursively bool _searchAndHighlightNodes(List 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 selectedIds = []; + List getSelectedIds(List nodes) { + List selectedIds = []; + for (var node in nodes) { + if (node.isChecked) { + selectedIds.add(node.uuid); + } + if (node.children.isNotEmpty) { + selectedIds.addAll(getSelectedIds(node.children)); + } + } + return selectedIds; + } + } diff --git a/lib/pages/roles_and_permission/users_page/bloc/users_event.dart b/lib/pages/roles_and_permission/users_page/bloc/users_event.dart index 77890673..f1675b08 100644 --- a/lib/pages/roles_and_permission/users_page/bloc/users_event.dart +++ b/lib/pages/roles_and_permission/users_page/bloc/users_event.dart @@ -10,6 +10,11 @@ class GetUsers extends UsersEvent { @override List get props => []; } +class CheckSpacesStepStatus extends UsersEvent { + const CheckSpacesStepStatus(); + @override + List get props => []; +} class LoadCommunityAndSpacesEvent extends UsersEvent { const LoadCommunityAndSpacesEvent(); @@ -49,3 +54,9 @@ class SearchAnode extends UsersEvent { @override List get props => [nodes, searchTerm]; } +class SelecteId extends UsersEvent { + List? nodes; + SelecteId({this.nodes,}); + @override + List get props => [nodes]; +} diff --git a/lib/pages/roles_and_permission/users_page/view/add_user_dialog.dart b/lib/pages/roles_and_permission/users_page/view/add_user_dialog.dart index 21e92727..895f4825 100644 --- a/lib/pages/roles_and_permission/users_page/view/add_user_dialog.dart +++ b/lib/pages/roles_and_permission/users_page/view/add_user_dialog.dart @@ -23,7 +23,8 @@ class _AddNewUserDialogState extends State { @override Widget build(BuildContext context) { return BlocProvider( - create: (BuildContext context) => UsersBloc()..add(LoadCommunityAndSpacesEvent()), + create: (BuildContext context) => + UsersBloc()..add(LoadCommunityAndSpacesEvent()), child: BlocConsumer( listener: (context, state) {}, builder: (context, state) { @@ -121,11 +122,11 @@ class _AddNewUserDialogState extends State { ), ], ), - ), - ], - ), - )); - })); + ), + ], + ), + )); + })); } Widget _getFormContent() { @@ -162,7 +163,9 @@ class _AddNewUserDialogState extends State { ? Assets.currentProcessIcon : bloc.isCompleteSpaces == false ? Assets.wrongProcessIcon - : Assets.uncomplete_ProcessIcon, + : bloc.isCompleteSpaces == true + ? Assets.completeProcessIcon + : Assets.uncomplete_ProcessIcon, width: 25, height: 25, ), @@ -263,6 +266,7 @@ class _AddNewUserDialogState extends State { onTap: () { setState(() { currentStep = step; + bloc.add(const CheckSpacesStepStatus()); }); }, child: Column( diff --git a/lib/pages/roles_and_permission/users_page/view/spaces_access_view.dart b/lib/pages/roles_and_permission/users_page/view/spaces_access_view.dart index 5dff9b0a..4bc330b2 100644 --- a/lib/pages/roles_and_permission/users_page/view/spaces_access_view.dart +++ b/lib/pages/roles_and_permission/users_page/view/spaces_access_view.dart @@ -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 { 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 { ); } - // 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 { } } - // 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 { (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 { (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 { } } - // 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 nodes, TreeNode target) { for (var node in nodes) { if (node.children.contains(target)) {