mirror of
https://github.com/SyncrowIOT/web.git
synced 2025-07-10 07:07:19 +00:00
add_user_dialog
This commit is contained in:
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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];
|
||||
}
|
||||
|
@ -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) {
|
||||
@ -121,11 +122,11 @@ class _AddNewUserDialogState extends State<AddNewUserDialog> {
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
));
|
||||
}));
|
||||
),
|
||||
],
|
||||
),
|
||||
));
|
||||
}));
|
||||
}
|
||||
|
||||
Widget _getFormContent() {
|
||||
@ -162,7 +163,9 @@ class _AddNewUserDialogState extends State<AddNewUserDialog> {
|
||||
? 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<AddNewUserDialog> {
|
||||
onTap: () {
|
||||
setState(() {
|
||||
currentStep = step;
|
||||
bloc.add(const CheckSpacesStepStatus());
|
||||
});
|
||||
},
|
||||
child: Column(
|
||||
|
@ -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)) {
|
||||
|
Reference in New Issue
Block a user