From b84513c09dc79624f70b3c04e761adeac4bcca46 Mon Sep 17 00:00:00 2001 From: hannathkadher Date: Fri, 28 Feb 2025 11:51:48 +0400 Subject: [PATCH 01/12] removed checkbox --- lib/common/widgets/custom_expansion_tile.dart | 32 ++++++------------- 1 file changed, 10 insertions(+), 22 deletions(-) diff --git a/lib/common/widgets/custom_expansion_tile.dart b/lib/common/widgets/custom_expansion_tile.dart index 8df9b663..3823b18f 100644 --- a/lib/common/widgets/custom_expansion_tile.dart +++ b/lib/common/widgets/custom_expansion_tile.dart @@ -56,24 +56,6 @@ class CustomExpansionTileState extends State { children: [ Row( children: [ - // Checkbox with independent state management - Checkbox( - value: false, - onChanged: (bool? value) { - setState(() {}); - }, - side: WidgetStateBorderSide.resolveWith((states) { - return const BorderSide(color: ColorsManager.grayBorder); - }), - fillColor: WidgetStateProperty.resolveWith((states) { - if (states.contains(WidgetState.selected)) { - return ColorsManager.grayBorder; - } else { - return ColorsManager.checkBoxFillColor; - } - }), - checkColor: ColorsManager.whiteColors, - ), // Expand/collapse icon, now wrapped in a GestureDetector for specific onTap if (widget.children != null && widget.children!.isNotEmpty) GestureDetector( @@ -84,7 +66,9 @@ class CustomExpansionTileState extends State { }); }, child: Icon( - _isExpanded ? Icons.keyboard_arrow_down : Icons.keyboard_arrow_right, + _isExpanded + ? Icons.keyboard_arrow_down + : Icons.keyboard_arrow_right, color: ColorsManager.lightGrayColor, size: 16.0, // Adjusted size for better alignment ), @@ -101,8 +85,10 @@ class CustomExpansionTileState extends State { _capitalizeFirstLetter(widget.title), style: TextStyle( color: widget.isSelected - ? ColorsManager.blackColor // Change color to black when selected - : ColorsManager.lightGrayColor, // Gray when not selected + ? ColorsManager + .blackColor // Change color to black when selected + : ColorsManager + .lightGrayColor, // Gray when not selected fontWeight: FontWeight.w400, ), ), @@ -111,7 +97,9 @@ class CustomExpansionTileState extends State { ], ), // The expanded section (children) that shows when the tile is expanded - if (_isExpanded && widget.children != null && widget.children!.isNotEmpty) + if (_isExpanded && + widget.children != null && + widget.children!.isNotEmpty) Padding( padding: const EdgeInsets.only(left: 48.0), // Indented children child: Column( From 7607e5f80dbad13ed3b585206b55560fb0d1a35d Mon Sep 17 00:00:00 2001 From: hannathkadher Date: Fri, 28 Feb 2025 19:37:50 +0400 Subject: [PATCH 02/12] reduced no of calls on load --- .../bloc/space_management_bloc.dart | 26 ++++++++++++------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/lib/pages/spaces_management/all_spaces/bloc/space_management_bloc.dart b/lib/pages/spaces_management/all_spaces/bloc/space_management_bloc.dart index 358bdd48..6dc847eb 100644 --- a/lib/pages/spaces_management/all_spaces/bloc/space_management_bloc.dart +++ b/lib/pages/spaces_management/all_spaces/bloc/space_management_bloc.dart @@ -18,9 +18,6 @@ import 'package:syncrow_web/services/product_api.dart'; import 'package:syncrow_web/services/space_mana_api.dart'; import 'package:syncrow_web/services/space_model_mang_api.dart'; import 'package:syncrow_web/utils/constants/action_enum.dart'; -import 'package:syncrow_web/utils/constants/strings_manager.dart'; -import 'package:syncrow_web/utils/constants/temp_const.dart'; -import 'package:syncrow_web/utils/helpers/shared_preferences_helper.dart'; class SpaceManagementBloc extends Bloc { @@ -231,12 +228,20 @@ class SpaceManagementBloc ) async { _logEvent('LoadCommunityAndSpacesEvent'); - var prevState = state; + // If already loaded, use cached data + if (state is SpaceManagementLoaded) { + emit(state); + return; + } + emit(SpaceManagementLoading()); + try { final projectUuid = await ProjectManager.getProjectUUID() ?? ''; + // Load products only once _onloadProducts(); + List communities = await _api.fetchCommunities(projectUuid); @@ -250,17 +255,20 @@ class SpaceManagementBloc updatedAt: community.updatedAt, name: community.name, description: community.description, - spaces: spaces, // New spaces list + spaces: spaces, region: community.region, ); }).toList(), ); - final prevSpaceModels = await fetchSpaceModels(prevState); + // Fetch space models only once + final prevSpaceModels = await fetchSpaceModels(state); + emit(SpaceManagementLoaded( - communities: updatedCommunities, - products: _cachedProducts ?? [], - spaceModels: prevSpaceModels)); + communities: updatedCommunities, + products: _cachedProducts ?? [], + spaceModels: prevSpaceModels, + )); } catch (e) { emit(SpaceManagementError('Error loading communities and spaces: $e')); } From 692b05a6005dd8de4ec26a2ec435ba765c3f5a31 Mon Sep 17 00:00:00 2001 From: hannathkadher Date: Sun, 2 Mar 2025 14:40:34 +0400 Subject: [PATCH 03/12] added update in space tree bloc --- .../access_management/bloc/access_bloc.dart | 3 - .../widgets/device_managment_body.dart | 1 - lib/pages/home/bloc/home_bloc.dart | 1 - .../space_tree/bloc/space_tree_bloc.dart | 9 + .../space_tree/bloc/space_tree_event.dart | 8 + .../bloc/space_management_bloc.dart | 222 ++++++++++-------- .../bloc/space_management_event.dart | 33 ++- .../view/spaces_management_page.dart | 6 +- .../widgets/blank_community_widget.dart | 9 +- .../view/center_body_widget.dart | 4 +- 10 files changed, 172 insertions(+), 124 deletions(-) diff --git a/lib/pages/access_management/bloc/access_bloc.dart b/lib/pages/access_management/bloc/access_bloc.dart index 4b1c37d6..562bd5b5 100644 --- a/lib/pages/access_management/bloc/access_bloc.dart +++ b/lib/pages/access_management/bloc/access_bloc.dart @@ -8,9 +8,6 @@ import 'package:syncrow_web/pages/common/hour_picker_dialog.dart'; import 'package:syncrow_web/services/access_mang_api.dart'; import 'package:syncrow_web/utils/color_manager.dart'; import 'package:syncrow_web/utils/constants/app_enum.dart'; -import 'package:syncrow_web/utils/constants/strings_manager.dart'; -import 'package:syncrow_web/utils/constants/temp_const.dart'; -import 'package:syncrow_web/utils/helpers/shared_preferences_helper.dart'; import 'package:syncrow_web/utils/snack_bar.dart'; class AccessBloc extends Bloc { diff --git a/lib/pages/device_managment/all_devices/widgets/device_managment_body.dart b/lib/pages/device_managment/all_devices/widgets/device_managment_body.dart index 52b2321c..9297c1fe 100644 --- a/lib/pages/device_managment/all_devices/widgets/device_managment_body.dart +++ b/lib/pages/device_managment/all_devices/widgets/device_managment_body.dart @@ -8,7 +8,6 @@ import 'package:syncrow_web/pages/device_managment/all_devices/models/devices_mo import 'package:syncrow_web/pages/device_managment/all_devices/widgets/device_search_filters.dart'; import 'package:syncrow_web/pages/device_managment/shared/device_batch_control_dialog.dart'; import 'package:syncrow_web/pages/device_managment/shared/device_control_dialog.dart'; -import 'package:syncrow_web/pages/space_tree/bloc/space_tree_bloc.dart'; import 'package:syncrow_web/pages/space_tree/view/space_tree_view.dart'; import 'package:syncrow_web/utils/format_date_time.dart'; import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart'; diff --git a/lib/pages/home/bloc/home_bloc.dart b/lib/pages/home/bloc/home_bloc.dart index 25b8b98d..04a02a11 100644 --- a/lib/pages/home/bloc/home_bloc.dart +++ b/lib/pages/home/bloc/home_bloc.dart @@ -83,7 +83,6 @@ class HomeBloc extends Bloc { try { emit(LoadingHome()); policy = await HomeApi().fetchPolicy(); - debugPrint("Fetched policy: $policy"); // Emit a state to trigger the UI update emit(HomeInitial()); } catch (e) { diff --git a/lib/pages/space_tree/bloc/space_tree_bloc.dart b/lib/pages/space_tree/bloc/space_tree_bloc.dart index e7fb4dc1..7820237b 100644 --- a/lib/pages/space_tree/bloc/space_tree_bloc.dart +++ b/lib/pages/space_tree/bloc/space_tree_bloc.dart @@ -16,6 +16,7 @@ class SpaceTreeBloc extends Bloc { on(_onSearch); on(_clearAllData); on(_clearCachedData); + on(_onCommunityAdded); } _fetchSpaces(InitialEvent event, Emitter emit) async { @@ -50,6 +51,14 @@ class SpaceTreeBloc extends Bloc { } } + void _onCommunityAdded(OnCommunityAdded event, Emitter emit) async { + final updatedCommunities = List.from(state.communityList); + updatedCommunities.add(event.newCommunity); + + emit(state.copyWith(communitiesList: updatedCommunities)); +} + + _onCommunityExpanded(OnCommunityExpanded event, Emitter emit) async { try { List updatedExpandedCommunityList = List.from(state.expandedCommunities); diff --git a/lib/pages/space_tree/bloc/space_tree_event.dart b/lib/pages/space_tree/bloc/space_tree_event.dart index e8fa996f..a22426f7 100644 --- a/lib/pages/space_tree/bloc/space_tree_event.dart +++ b/lib/pages/space_tree/bloc/space_tree_event.dart @@ -69,6 +69,14 @@ class SearchQueryEvent extends SpaceTreeEvent { List get props => [searchQuery]; } +class OnCommunityAdded extends SpaceTreeEvent { + final CommunityModel newCommunity; + const OnCommunityAdded(this.newCommunity); + + @override + List get props => [newCommunity]; +} + class ClearAllData extends SpaceTreeEvent {} class ClearCachedData extends SpaceTreeEvent {} diff --git a/lib/pages/spaces_management/all_spaces/bloc/space_management_bloc.dart b/lib/pages/spaces_management/all_spaces/bloc/space_management_bloc.dart index 6dc847eb..cb5de57e 100644 --- a/lib/pages/spaces_management/all_spaces/bloc/space_management_bloc.dart +++ b/lib/pages/spaces_management/all_spaces/bloc/space_management_bloc.dart @@ -1,8 +1,10 @@ import 'dart:developer'; +import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; -import 'package:shared_preferences/shared_preferences.dart'; import 'package:syncrow_web/pages/common/bloc/project_manager.dart'; +import 'package:syncrow_web/pages/space_tree/bloc/space_tree_bloc.dart'; +import 'package:syncrow_web/pages/space_tree/bloc/space_tree_event.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/community_model.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/create_subspace_model.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/product_model.dart'; @@ -17,7 +19,7 @@ import 'package:syncrow_web/pages/spaces_management/space_model/models/tag_updat import 'package:syncrow_web/services/product_api.dart'; import 'package:syncrow_web/services/space_mana_api.dart'; import 'package:syncrow_web/services/space_model_mang_api.dart'; -import 'package:syncrow_web/utils/constants/action_enum.dart'; +import 'package:syncrow_web/utils/constants/action_enum.dart' as custom_action; class SpaceManagementBloc extends Bloc { @@ -30,7 +32,6 @@ class SpaceManagementBloc SpaceManagementBloc(this._api, this._productApi, this._spaceModelApi) : super(SpaceManagementInitial()) { on(_onLoadCommunityAndSpaces); - on(_onUpdateSpacePosition); on(_onCreateCommunity); on(_onSelectCommunity); on(_onCommunityDelete); @@ -182,6 +183,8 @@ class SpaceManagementBloc try { final previousState = state; final projectUuid = await ProjectManager.getProjectUUID() ?? ''; + var spaceBloc = event.context.read(); + List communities = spaceBloc.state.communityList; var prevSpaceModels = await fetchSpaceModels(previousState); @@ -196,25 +199,31 @@ class SpaceManagementBloc return; } - final communities = await _api.fetchCommunities(projectUuid); - final updatedCommunities = - await Future.wait(communities.map((community) async { - final spaces = await _fetchSpacesForCommunity(community.uuid); + if (communities.isEmpty) { + communities = await _api.fetchCommunities(projectUuid); - return CommunityModel( - uuid: community.uuid, - createdAt: community.createdAt, - updatedAt: community.updatedAt, - name: community.name, - description: community.description, - spaces: spaces, - region: community.region, + List updatedCommunities = await Future.wait( + communities.map((community) async { + List spaces = + await _fetchSpacesForCommunity(community.uuid); + return CommunityModel( + uuid: community.uuid, + createdAt: community.createdAt, + updatedAt: community.updatedAt, + name: community.name, + description: community.description, + spaces: spaces, + region: community.region, + ); + }).toList(), ); - })); + + communities = updatedCommunities; + } emit(BlankState( spaceModels: prevSpaceModels, - communities: updatedCommunities, + communities: communities, products: _cachedProducts ?? [], )); } catch (error) { @@ -228,50 +237,49 @@ class SpaceManagementBloc ) async { _logEvent('LoadCommunityAndSpacesEvent'); - // If already loaded, use cached data - if (state is SpaceManagementLoaded) { - emit(state); - return; + var spaceBloc = event.context.read(); + List communities = spaceBloc.state.communityList; + + if (communities.isEmpty) { + _logEvent("community is empty"); + emit(SpaceManagementLoading()); + + try { + final projectUuid = await ProjectManager.getProjectUUID() ?? ''; + _onloadProducts(); + + /* communities = await _api.fetchCommunities(projectUuid); + + List updatedCommunities = await Future.wait( + communities.map((community) async { + List spaces = + await _fetchSpacesForCommunity(community.uuid); + return CommunityModel( + uuid: community.uuid, + createdAt: community.createdAt, + updatedAt: community.updatedAt, + name: community.name, + description: community.description, + spaces: spaces, + region: community.region, + ); + }).toList(), + ); + + communities = updatedCommunities; */ + } catch (e) { + emit(SpaceManagementError('Error loading communities and spaces: $e')); + return; + } } - emit(SpaceManagementLoading()); + final prevSpaceModels = await fetchSpaceModels(state); - try { - final projectUuid = await ProjectManager.getProjectUUID() ?? ''; - - // Load products only once - _onloadProducts(); - - List communities = - await _api.fetchCommunities(projectUuid); - - List updatedCommunities = await Future.wait( - communities.map((community) async { - List spaces = - await _fetchSpacesForCommunity(community.uuid); - return CommunityModel( - uuid: community.uuid, - createdAt: community.createdAt, - updatedAt: community.updatedAt, - name: community.name, - description: community.description, - spaces: spaces, - region: community.region, - ); - }).toList(), - ); - - // Fetch space models only once - final prevSpaceModels = await fetchSpaceModels(state); - - emit(SpaceManagementLoaded( - communities: updatedCommunities, - products: _cachedProducts ?? [], - spaceModels: prevSpaceModels, - )); - } catch (e) { - emit(SpaceManagementError('Error loading communities and spaces: $e')); - } + emit(SpaceManagementLoaded( + communities: communities, + products: _cachedProducts ?? [], + spaceModels: prevSpaceModels, + )); } void _onCommunityDelete( @@ -285,7 +293,7 @@ class SpaceManagementBloc final success = await _api.deleteCommunity(event.communityUuid, projectUuid); if (success) { - add(LoadCommunityAndSpacesEvent()); + // add(LoadCommunityAndSpacesEvent()); } else { emit(const SpaceManagementError('Failed to delete the community.')); } @@ -295,11 +303,6 @@ class SpaceManagementBloc } } - void _onUpdateSpacePosition( - UpdateSpacePositionEvent event, - Emitter emit, - ) {} - void _onCreateCommunity( CreateCommunityEvent event, Emitter emit, @@ -309,6 +312,8 @@ class SpaceManagementBloc try { final projectUuid = await ProjectManager.getProjectUUID() ?? ''; + final BuildContext safeContext = + event.context; // Capture context safely before async calls CommunityModel? newCommunity = await _api.createCommunity( event.name, event.description, projectUuid); @@ -321,6 +326,16 @@ class SpaceManagementBloc (previousState as dynamic).communities, ); final updatedCommunities = prevCommunities..add(newCommunity); + + if (safeContext.mounted) { + print("added"); + final spaceTreeBloc = safeContext.read< + SpaceTreeBloc>(); // ✅ Read bloc only when context is mounted + spaceTreeBloc.add(OnCommunityAdded(newCommunity)); + } else { + print("not mounted"); + } + emit(SpaceManagementLoaded( spaceModels: prevSpaceModels, communities: updatedCommunities, @@ -416,7 +431,7 @@ class SpaceManagementBloc emit, ); } else { - add(LoadCommunityAndSpacesEvent()); + // add(LoadCommunityAndSpacesEvent()); } } catch (e) { emit(SpaceManagementError('Error saving spaces: $e')); @@ -491,13 +506,15 @@ class SpaceManagementBloc .any((subspace) => subspace.uuid == prevSubspace.uuid); if (!existsInNew) { subspaceUpdates.add(UpdateSubspaceTemplateModel( - action: Action.delete, uuid: prevSubspace.uuid)); + action: custom_action.Action.delete, + uuid: prevSubspace.uuid)); } } } else if (prevSubspaces != null && newSubspaces == null) { for (var prevSubspace in prevSubspaces) { subspaceUpdates.add(UpdateSubspaceTemplateModel( - action: Action.delete, uuid: prevSubspace.uuid)); + action: custom_action.Action.delete, + uuid: prevSubspace.uuid)); } } @@ -510,14 +527,14 @@ class SpaceManagementBloc if (newSubspace.tags != null) { for (var tag in newSubspace.tags!) { tagUpdates.add(TagModelUpdate( - action: Action.add, + action: custom_action.Action.add, uuid: tag.uuid == '' ? null : tag.uuid, tag: tag.tag, productUuid: tag.product?.uuid)); } } subspaceUpdates.add(UpdateSubspaceTemplateModel( - action: Action.add, + action: custom_action.Action.add, subspaceName: newSubspace.subspaceName, tags: tagUpdates)); } @@ -536,7 +553,7 @@ class SpaceManagementBloc final List tagSubspaceUpdates = processTagUpdates(prevSubspace.tags, newSubspace.tags); subspaceUpdates.add(UpdateSubspaceTemplateModel( - action: Action.update, + action: custom_action.Action.update, uuid: newSubspace.uuid, subspaceName: newSubspace.subspaceName, tags: tagSubspaceUpdates)); @@ -623,35 +640,42 @@ class SpaceManagementBloc void _onLoadSpaceModel( SpaceModelLoadEvent event, Emitter emit) async { emit(SpaceManagementLoading()); + try { var prevState = state; final projectUuid = await ProjectManager.getProjectUUID() ?? ''; - - List communities = - await _api.fetchCommunities(projectUuid); - - List updatedCommunities = await Future.wait( - communities.map((community) async { - List spaces = - await _fetchSpacesForCommunity(community.uuid); - return CommunityModel( - uuid: community.uuid, - createdAt: community.createdAt, - updatedAt: community.updatedAt, - name: community.name, - description: community.description, - spaces: spaces, // New spaces list - region: community.region, - ); - }).toList(), - ); + var spaceBloc = event.context.read(); + List communities = spaceBloc.state.communityList; var prevSpaceModels = await fetchSpaceModels(prevState); + if (communities.isEmpty) { + communities = await _api.fetchCommunities(projectUuid); + + List updatedCommunities = await Future.wait( + communities.map((community) async { + List spaces = + await _fetchSpacesForCommunity(community.uuid); + return CommunityModel( + uuid: community.uuid, + createdAt: community.createdAt, + updatedAt: community.updatedAt, + name: community.name, + description: community.description, + spaces: spaces, + region: community.region, + ); + }).toList(), + ); + + communities = updatedCommunities; + } + emit(SpaceModelLoaded( - communities: updatedCommunities, - products: _cachedProducts ?? [], - spaceModels: prevSpaceModels)); + communities: communities, + products: _cachedProducts ?? [], + spaceModels: prevSpaceModels, + )); } catch (e) { emit(SpaceManagementError('Error loading communities and spaces: $e')); } @@ -667,7 +691,7 @@ class SpaceManagementBloc if (prevTags == null && newTags != null) { for (var newTag in newTags) { tagUpdates.add(TagModelUpdate( - action: Action.add, + action: custom_action.Action.add, tag: newTag.tag, uuid: newTag.uuid, productUuid: newTag.product?.uuid, @@ -683,14 +707,14 @@ class SpaceManagementBloc final existsInNew = newTags.any((newTag) => newTag.uuid == prevTag.uuid); if (!existsInNew) { - tagUpdates - .add(TagModelUpdate(action: Action.delete, uuid: prevTag.uuid)); + tagUpdates.add(TagModelUpdate( + action: custom_action.Action.delete, uuid: prevTag.uuid)); } } } else if (prevTags != null && newTags == null) { for (var prevTag in prevTags) { - tagUpdates - .add(TagModelUpdate(action: Action.delete, uuid: prevTag.uuid)); + tagUpdates.add(TagModelUpdate( + action: custom_action.Action.delete, uuid: prevTag.uuid)); } } @@ -703,7 +727,7 @@ class SpaceManagementBloc if ((newTag.uuid == null || !prevTagUuids.contains(newTag.uuid)) && !processedTags.contains(newTag.tag)) { tagUpdates.add(TagModelUpdate( - action: Action.add, + action: custom_action.Action.add, tag: newTag.tag, uuid: newTag.uuid == '' ? null : newTag.uuid, productUuid: newTag.product?.uuid)); @@ -720,7 +744,7 @@ class SpaceManagementBloc final newTag = newTagMap[prevTag.uuid]; if (newTag != null) { tagUpdates.add(TagModelUpdate( - action: Action.update, + action: custom_action.Action.update, uuid: newTag.uuid, tag: newTag.tag, )); diff --git a/lib/pages/spaces_management/all_spaces/bloc/space_management_event.dart b/lib/pages/spaces_management/all_spaces/bloc/space_management_event.dart index d25534b4..38e4bfb3 100644 --- a/lib/pages/spaces_management/all_spaces/bloc/space_management_event.dart +++ b/lib/pages/spaces_management/all_spaces/bloc/space_management_event.dart @@ -7,10 +7,16 @@ abstract class SpaceManagementEvent extends Equatable { const SpaceManagementEvent(); @override - List get props => []; + List get props => []; } -class LoadCommunityAndSpacesEvent extends SpaceManagementEvent {} +class LoadCommunityAndSpacesEvent extends SpaceManagementEvent { + final BuildContext context; + + const LoadCommunityAndSpacesEvent(this.context); + @override + List get props => [context]; +} class DeleteCommunityEvent extends SpaceManagementEvent { final String communityUuid; @@ -74,14 +80,12 @@ class UpdateSpacePositionEvent extends SpaceManagementEvent { class CreateCommunityEvent extends SpaceManagementEvent { final String name; final String description; + final BuildContext context; - const CreateCommunityEvent({ - required this.name, - required this.description, - }); + const CreateCommunityEvent(this.name, this.description, this.context); @override - List get props => [name, description]; + List get props => [name, description, context]; } class UpdateCommunityEvent extends SpaceManagementEvent { @@ -141,7 +145,18 @@ class LoadSpaceHierarchyEvent extends SpaceManagementEvent { List get props => [communityId]; } +class BlankStateEvent extends SpaceManagementEvent { + final BuildContext context; -class BlankStateEvent extends SpaceManagementEvent {} + const BlankStateEvent(this.context); + @override + List get props => [context]; +} -class SpaceModelLoadEvent extends SpaceManagementEvent {} +class SpaceModelLoadEvent extends SpaceManagementEvent { + final BuildContext context; + + const SpaceModelLoadEvent(this.context); + @override + List get props => [context]; +} diff --git a/lib/pages/spaces_management/all_spaces/view/spaces_management_page.dart b/lib/pages/spaces_management/all_spaces/view/spaces_management_page.dart index 02000e1a..d5db20eb 100644 --- a/lib/pages/spaces_management/all_spaces/view/spaces_management_page.dart +++ b/lib/pages/spaces_management/all_spaces/view/spaces_management_page.dart @@ -28,14 +28,14 @@ class SpaceManagementPageState extends State { return MultiBlocProvider( providers: [ BlocProvider( - create: (_) => SpaceManagementBloc( + create: (context) => SpaceManagementBloc( _api, _productApi, _spaceModelApi, - )..add(LoadCommunityAndSpacesEvent()), + )..add(LoadCommunityAndSpacesEvent(this.context)), ), BlocProvider( - create: (_) => CenterBodyBloc(), + create: (context) => CenterBodyBloc(), ), ], child: WebScaffold( diff --git a/lib/pages/spaces_management/all_spaces/widgets/blank_community_widget.dart b/lib/pages/spaces_management/all_spaces/widgets/blank_community_widget.dart index 999c27bd..66f1a026 100644 --- a/lib/pages/spaces_management/all_spaces/widgets/blank_community_widget.dart +++ b/lib/pages/spaces_management/all_spaces/widgets/blank_community_widget.dart @@ -73,17 +73,14 @@ class _BlankCommunityWidgetState extends State { context: parentContext, builder: (context) => CreateCommunityDialog( isEditMode: false, - existingCommunityNames: widget.communities.map((community) => community.name).toList(), + existingCommunityNames: + widget.communities.map((community) => community.name).toList(), onCreateCommunity: (String communityName, String description) { parentContext.read().add( - CreateCommunityEvent( - name: communityName, - description: description, - ), + CreateCommunityEvent(communityName, description, context), ); }, ), ); } - } diff --git a/lib/pages/spaces_management/structure_selector/view/center_body_widget.dart b/lib/pages/spaces_management/structure_selector/view/center_body_widget.dart index 45a6aaf7..0f40ddbb 100644 --- a/lib/pages/spaces_management/structure_selector/view/center_body_widget.dart +++ b/lib/pages/spaces_management/structure_selector/view/center_body_widget.dart @@ -15,11 +15,11 @@ class CenterBodyWidget extends StatelessWidget { context.read().add(CommunityStructureSelectedEvent()); } if (state is CommunityStructureState) { - context.read().add(BlankStateEvent()); + context.read().add(BlankStateEvent(context)); } if (state is SpaceModelState) { - context.read().add(SpaceModelLoadEvent()); + context.read().add(SpaceModelLoadEvent(context)); } return Container( From c7c8e9a519aeb1004d014f05612b7a47f0fce06b Mon Sep 17 00:00:00 2001 From: hannathkadher Date: Tue, 4 Mar 2025 11:40:06 +0400 Subject: [PATCH 04/12] cached space models --- .../bloc/space_management_bloc.dart | 135 ++++++++---------- .../bloc/create_space_model_bloc.dart | 3 - 2 files changed, 60 insertions(+), 78 deletions(-) diff --git a/lib/pages/spaces_management/all_spaces/bloc/space_management_bloc.dart b/lib/pages/spaces_management/all_spaces/bloc/space_management_bloc.dart index cb5de57e..84dc2442 100644 --- a/lib/pages/spaces_management/all_spaces/bloc/space_management_bloc.dart +++ b/lib/pages/spaces_management/all_spaces/bloc/space_management_bloc.dart @@ -1,3 +1,4 @@ +import 'dart:async'; import 'dart:developer'; import 'package:flutter/material.dart'; @@ -28,6 +29,7 @@ class SpaceManagementBloc final SpaceModelManagementApi _spaceModelApi; List? _cachedProducts; + List? _cachedSpaceModels; SpaceManagementBloc(this._api, this._productApi, this._spaceModelApi) : super(SpaceManagementInitial()) { @@ -48,6 +50,38 @@ class SpaceManagementBloc log('Event Triggered: $eventName'); } + Future> fetchSpaceModels( + SpaceManagementState previousState) async { + try { + if (_cachedSpaceModels != null) { + return _cachedSpaceModels!; + } + + final projectUuid = await ProjectManager.getProjectUUID() ?? ''; + + List allSpaceModels = []; + + bool hasNext = true; + int page = 1; + + while (hasNext) { + final spaceModels = await _spaceModelApi.listSpaceModels( + page: page, projectId: projectUuid); + if (spaceModels.isNotEmpty) { + allSpaceModels.addAll(spaceModels); + page++; + } else { + hasNext = false; + } + } + + _cachedSpaceModels = allSpaceModels; + return allSpaceModels; + } catch (e) { + return []; + } + } + void _onUpdateCommunity( UpdateCommunityEvent event, Emitter emit, @@ -89,46 +123,7 @@ class SpaceManagementBloc } } - Future> fetchSpaceModels( - SpaceManagementState previousState) async { - try { - final projectUuid = await ProjectManager.getProjectUUID() ?? ''; - - List allSpaces = []; - List prevSpaceModels = []; - - if (previousState is SpaceManagementLoaded || - previousState is BlankState) { - prevSpaceModels = List.from( - (previousState as dynamic).spaceModels ?? [], - ); - allSpaces.addAll(prevSpaceModels); - } - - if (prevSpaceModels.isEmpty) { - bool hasNext = true; - int page = 1; - - while (hasNext) { - final spaces = await _spaceModelApi.listSpaceModels( - page: page, projectId: projectUuid); - if (spaces.isNotEmpty) { - allSpaces.addAll(spaces); - page++; - } else { - hasNext = false; - } - } - prevSpaceModels = await _spaceModelApi.listSpaceModels( - page: 1, projectId: projectUuid); - } - - return allSpaces; - } catch (e) { - return []; - } - } - + void _onloadProducts() async { if (_cachedProducts == null) { final products = await _productApi.fetchProducts(); @@ -184,7 +179,7 @@ class SpaceManagementBloc final previousState = state; final projectUuid = await ProjectManager.getProjectUUID() ?? ''; var spaceBloc = event.context.read(); - List communities = spaceBloc.state.communityList; + List communities = await _waitForCommunityList(spaceBloc); var prevSpaceModels = await fetchSpaceModels(previousState); @@ -238,43 +233,13 @@ class SpaceManagementBloc _logEvent('LoadCommunityAndSpacesEvent'); var spaceBloc = event.context.read(); - List communities = spaceBloc.state.communityList; + _onloadProducts(); - if (communities.isEmpty) { - _logEvent("community is empty"); - emit(SpaceManagementLoading()); - - try { - final projectUuid = await ProjectManager.getProjectUUID() ?? ''; - _onloadProducts(); - - /* communities = await _api.fetchCommunities(projectUuid); - - List updatedCommunities = await Future.wait( - communities.map((community) async { - List spaces = - await _fetchSpacesForCommunity(community.uuid); - return CommunityModel( - uuid: community.uuid, - createdAt: community.createdAt, - updatedAt: community.updatedAt, - name: community.name, - description: community.description, - spaces: spaces, - region: community.region, - ); - }).toList(), - ); - - communities = updatedCommunities; */ - } catch (e) { - emit(SpaceManagementError('Error loading communities and spaces: $e')); - return; - } - } + // Wait until `communityList` is loaded + List communities = await _waitForCommunityList(spaceBloc); + // Fetch space models after communities are available final prevSpaceModels = await fetchSpaceModels(state); - emit(SpaceManagementLoaded( communities: communities, products: _cachedProducts ?? [], @@ -282,6 +247,26 @@ class SpaceManagementBloc )); } + Future> _waitForCommunityList( + SpaceTreeBloc spaceBloc) async { + // Check if communityList is already populated + if (spaceBloc.state.communityList.isNotEmpty) { + return spaceBloc.state.communityList; + } + + final completer = Completer>(); + final subscription = spaceBloc.stream.listen((state) { + if (state.communityList.isNotEmpty) { + completer.complete(state.communityList); + } + }); + + // Return the list once available, then cancel the listener + final communities = await completer.future; + await subscription.cancel(); + return communities; + } + void _onCommunityDelete( DeleteCommunityEvent event, Emitter emit, diff --git a/lib/pages/spaces_management/space_model/bloc/create_space_model_bloc.dart b/lib/pages/spaces_management/space_model/bloc/create_space_model_bloc.dart index 7c68e15c..8237c172 100644 --- a/lib/pages/spaces_management/space_model/bloc/create_space_model_bloc.dart +++ b/lib/pages/spaces_management/space_model/bloc/create_space_model_bloc.dart @@ -9,9 +9,6 @@ import 'package:syncrow_web/pages/spaces_management/space_model/models/tag_model import 'package:syncrow_web/pages/spaces_management/space_model/models/tag_update_model.dart'; import 'package:syncrow_web/services/space_model_mang_api.dart'; import 'package:syncrow_web/utils/constants/action_enum.dart'; -import 'package:syncrow_web/utils/constants/strings_manager.dart'; -import 'package:syncrow_web/utils/constants/temp_const.dart'; -import 'package:syncrow_web/utils/helpers/shared_preferences_helper.dart'; class CreateSpaceModelBloc extends Bloc { From 4469efe4651b12386e0c25d0ae6754994266c13a Mon Sep 17 00:00:00 2001 From: hannathkadher Date: Tue, 4 Mar 2025 20:51:21 +0400 Subject: [PATCH 05/12] cached space model --- .../bloc/space_management_bloc.dart | 9 ++-- .../bloc/space_management_state.dart | 4 -- .../view/spaces_management_page.dart | 3 ++ .../widgets/loaded_space_widget.dart | 42 +++++++++++-------- .../space_model/bloc/space_model_bloc.dart | 4 ++ 5 files changed, 34 insertions(+), 28 deletions(-) diff --git a/lib/pages/spaces_management/all_spaces/bloc/space_management_bloc.dart b/lib/pages/spaces_management/all_spaces/bloc/space_management_bloc.dart index 84dc2442..3b7b2626 100644 --- a/lib/pages/spaces_management/all_spaces/bloc/space_management_bloc.dart +++ b/lib/pages/spaces_management/all_spaces/bloc/space_management_bloc.dart @@ -75,7 +75,8 @@ class SpaceManagementBloc } } - _cachedSpaceModels = allSpaceModels; + _cachedSpaceModels = allSpaceModels; + return allSpaceModels; } catch (e) { return []; @@ -123,7 +124,6 @@ class SpaceManagementBloc } } - void _onloadProducts() async { if (_cachedProducts == null) { final products = await _productApi.fetchProducts(); @@ -313,13 +313,10 @@ class SpaceManagementBloc final updatedCommunities = prevCommunities..add(newCommunity); if (safeContext.mounted) { - print("added"); final spaceTreeBloc = safeContext.read< SpaceTreeBloc>(); // ✅ Read bloc only when context is mounted spaceTreeBloc.add(OnCommunityAdded(newCommunity)); - } else { - print("not mounted"); - } + } emit(SpaceManagementLoaded( spaceModels: prevSpaceModels, diff --git a/lib/pages/spaces_management/all_spaces/bloc/space_management_state.dart b/lib/pages/spaces_management/all_spaces/bloc/space_management_state.dart index 571651e5..10a02294 100644 --- a/lib/pages/spaces_management/all_spaces/bloc/space_management_state.dart +++ b/lib/pages/spaces_management/all_spaces/bloc/space_management_state.dart @@ -30,10 +30,6 @@ class SpaceManagementLoaded extends SpaceManagementState { this.spaceModels}); } -class SpaceModelManagenetLoaded extends SpaceManagementState { - SpaceModelManagenetLoaded(); -} - class BlankState extends SpaceManagementState { final List communities; final List products; diff --git a/lib/pages/spaces_management/all_spaces/view/spaces_management_page.dart b/lib/pages/spaces_management/all_spaces/view/spaces_management_page.dart index d5db20eb..6c30e03b 100644 --- a/lib/pages/spaces_management/all_spaces/view/spaces_management_page.dart +++ b/lib/pages/spaces_management/all_spaces/view/spaces_management_page.dart @@ -1,3 +1,5 @@ +import 'dart:developer'; + import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:syncrow_web/pages/device_managment/shared/navigate_home_grid_view.dart'; @@ -57,6 +59,7 @@ class SpaceManagementPageState extends State { shouldNavigateToSpaceModelPage: false, ); } else if (state is SpaceManagementLoaded) { + return LoadedSpaceView( communities: state.communities, selectedCommunity: state.selectedCommunity, diff --git a/lib/pages/spaces_management/all_spaces/widgets/loaded_space_widget.dart b/lib/pages/spaces_management/all_spaces/widgets/loaded_space_widget.dart index dccd7fd9..4d6fc3fb 100644 --- a/lib/pages/spaces_management/all_spaces/widgets/loaded_space_widget.dart +++ b/lib/pages/spaces_management/all_spaces/widgets/loaded_space_widget.dart @@ -40,6 +40,7 @@ class _LoadedSpaceViewState extends State { @override void initState() { super.initState(); + _spaceModels = List.from(widget.spaceModels ?? []); } @@ -47,6 +48,7 @@ class _LoadedSpaceViewState extends State { @override void didUpdateWidget(covariant LoadedSpaceView oldWidget) { super.didUpdateWidget(oldWidget); + if (widget.spaceModels != oldWidget.spaceModels) { WidgetsBinding.instance.addPostFrameCallback((_) { if (mounted) { @@ -76,29 +78,33 @@ class _LoadedSpaceViewState extends State { clipBehavior: Clip.none, children: [ widget.shouldNavigateToSpaceModelPage - ? Row( - children: [ - SizedBox(width: 300, child: SpaceTreeView(onSelect: () {})), - Expanded( - child: BlocProvider( - create: (context) => SpaceModelBloc( - api: SpaceModelManagementApi(), - initialSpaceModels: _spaceModels, + ? _spaceModels.isNotEmpty + ? Row( + children: [ + SizedBox( + width: 300, child: SpaceTreeView(onSelect: () {})), + Expanded( + child: BlocProvider( + create: (context) => SpaceModelBloc( + api: SpaceModelManagementApi(), + initialSpaceModels: _spaceModels, + ), + child: SpaceModelPage( + products: widget.products, + onSpaceModelsUpdated: _onSpaceModelsUpdated, + ), + ), ), - child: SpaceModelPage( - products: widget.products, - onSpaceModelsUpdated: _onSpaceModelsUpdated, - ), - ), - ), - ], - ) + ], + ) + : const Center(child: CircularProgressIndicator()) : Row( children: [ SidebarWidget( communities: widget.communities, - selectedSpaceUuid: - widget.selectedSpace?.uuid ?? widget.selectedCommunity?.uuid ?? '', + selectedSpaceUuid: widget.selectedSpace?.uuid ?? + widget.selectedCommunity?.uuid ?? + '', ), CommunityStructureArea( selectedCommunity: widget.selectedCommunity, diff --git a/lib/pages/spaces_management/space_model/bloc/space_model_bloc.dart b/lib/pages/spaces_management/space_model/bloc/space_model_bloc.dart index 16ba41c0..ed6ffa71 100644 --- a/lib/pages/spaces_management/space_model/bloc/space_model_bloc.dart +++ b/lib/pages/spaces_management/space_model/bloc/space_model_bloc.dart @@ -1,3 +1,5 @@ +import 'dart:developer'; + import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:syncrow_web/pages/common/bloc/project_manager.dart'; import 'package:syncrow_web/pages/spaces_management/space_model/bloc/space_model_event.dart'; @@ -12,6 +14,8 @@ class SpaceModelBloc extends Bloc { required this.api, required List initialSpaceModels, }) : super(SpaceModelLoaded(spaceModels: initialSpaceModels)) { + log('Initial Space Models in: ${initialSpaceModels.map((e) => e.toJson()).toList()}'); + on(_onCreateSpaceModel); on(_onUpdateSpaceModel); on(_onDeleteSpaceModel); From 51cfa8d5ae97fc079465e8724b1a3886d6800e73 Mon Sep 17 00:00:00 2001 From: hannathkadher Date: Wed, 5 Mar 2025 12:21:47 +0400 Subject: [PATCH 06/12] cached space models --- .../bloc/space_management_bloc.dart | 88 ++++++++++++++----- .../bloc/space_management_event.dart | 13 ++- .../bloc/space_management_state.dart | 1 + .../view/spaces_management_page.dart | 2 + 4 files changed, 81 insertions(+), 23 deletions(-) diff --git a/lib/pages/spaces_management/all_spaces/bloc/space_management_bloc.dart b/lib/pages/spaces_management/all_spaces/bloc/space_management_bloc.dart index 3b7b2626..ddc294d7 100644 --- a/lib/pages/spaces_management/all_spaces/bloc/space_management_bloc.dart +++ b/lib/pages/spaces_management/all_spaces/bloc/space_management_bloc.dart @@ -1,7 +1,5 @@ import 'dart:async'; import 'dart:developer'; - -import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:syncrow_web/pages/common/bloc/project_manager.dart'; import 'package:syncrow_web/pages/space_tree/bloc/space_tree_bloc.dart'; @@ -30,9 +28,14 @@ class SpaceManagementBloc List? _cachedProducts; List? _cachedSpaceModels; + final SpaceTreeBloc _spaceTreeBloc; - SpaceManagementBloc(this._api, this._productApi, this._spaceModelApi) - : super(SpaceManagementInitial()) { + SpaceManagementBloc( + this._api, + this._productApi, + this._spaceModelApi, + this._spaceTreeBloc, + ) : super(SpaceManagementInitial()) { on(_onLoadCommunityAndSpaces); on(_onCreateCommunity); on(_onSelectCommunity); @@ -44,14 +47,63 @@ class SpaceManagementBloc on(_onNewCommunity); on(_onBlankState); on(_onLoadSpaceModel); + on(_updateSpaceModelCache); + on(_deleteSpaceModelFromCache); + } + + Future _updateSpaceModelCache( + UpdateSpaceModelCache event, Emitter emit) async { + if (_cachedSpaceModels != null) { + _cachedSpaceModels = _cachedSpaceModels!.map((model) { + return model.uuid == event.updatedModel.uuid + ? event.updatedModel + : model; + }).toList(); + } else { + _cachedSpaceModels = await fetchSpaceModels(); + } + + emit(SpaceModelLoaded( + communities: state is SpaceManagementLoaded + ? (state as SpaceManagementLoaded).communities + : [], + products: _cachedProducts ?? [], + spaceModels: List.from(_cachedSpaceModels ?? []), + )); + } + + void _deleteSpaceModelFromCache(DeleteSpaceModelFromCache event, + Emitter emit) async { + if (_cachedSpaceModels != null) { + _cachedSpaceModels = _cachedSpaceModels! + .where((model) => model.uuid != event.deletedUuid) + .toList(); + } else { + _cachedSpaceModels = await fetchSpaceModels(); + } + + emit(SpaceModelLoaded( + communities: state is SpaceManagementLoaded + ? (state as SpaceManagementLoaded).communities + : [], + products: _cachedProducts ?? [], + spaceModels: List.from(_cachedSpaceModels ?? []), + )); } void _logEvent(String eventName) { log('Event Triggered: $eventName'); } - Future> fetchSpaceModels( - SpaceManagementState previousState) async { + void updateCachedSpaceModels(List updatedModels) { + _cachedSpaceModels = List.from(updatedModels); + } + + void addToCachedSpaceModels(SpaceTemplateModel newModel) { + _cachedSpaceModels?.add(newModel); + } + + Future> fetchSpaceModels() async { try { if (_cachedSpaceModels != null) { return _cachedSpaceModels!; @@ -87,7 +139,6 @@ class SpaceManagementBloc UpdateCommunityEvent event, Emitter emit, ) async { - _logEvent('UpdateCommunityEvent'); final previousState = state; try { @@ -107,7 +158,7 @@ class SpaceManagementBloc } } - var prevSpaceModels = await fetchSpaceModels(previousState); + var prevSpaceModels = await fetchSpaceModels(); emit(SpaceManagementLoaded( communities: updatedCommunities, @@ -161,7 +212,7 @@ class SpaceManagementBloc return; } - var prevSpaceModels = await fetchSpaceModels(previousState); + var prevSpaceModels = await fetchSpaceModels(); emit(BlankState( communities: event.communities, @@ -181,7 +232,7 @@ class SpaceManagementBloc var spaceBloc = event.context.read(); List communities = await _waitForCommunityList(spaceBloc); - var prevSpaceModels = await fetchSpaceModels(previousState); + var prevSpaceModels = await fetchSpaceModels(); if (previousState is SpaceManagementLoaded || previousState is BlankState) { @@ -239,7 +290,7 @@ class SpaceManagementBloc List communities = await _waitForCommunityList(spaceBloc); // Fetch space models after communities are available - final prevSpaceModels = await fetchSpaceModels(state); + final prevSpaceModels = await fetchSpaceModels(); emit(SpaceManagementLoaded( communities: communities, products: _cachedProducts ?? [], @@ -297,12 +348,10 @@ class SpaceManagementBloc try { final projectUuid = await ProjectManager.getProjectUUID() ?? ''; - final BuildContext safeContext = - event.context; // Capture context safely before async calls CommunityModel? newCommunity = await _api.createCommunity( event.name, event.description, projectUuid); - var prevSpaceModels = await fetchSpaceModels(previousState); + var prevSpaceModels = await fetchSpaceModels(); if (newCommunity != null) { if (previousState is SpaceManagementLoaded || @@ -311,12 +360,7 @@ class SpaceManagementBloc (previousState as dynamic).communities, ); final updatedCommunities = prevCommunities..add(newCommunity); - - if (safeContext.mounted) { - final spaceTreeBloc = safeContext.read< - SpaceTreeBloc>(); // ✅ Read bloc only when context is mounted - spaceTreeBloc.add(OnCommunityAdded(newCommunity)); - } + _spaceTreeBloc.add(OnCommunityAdded(newCommunity)); emit(SpaceManagementLoaded( spaceModels: prevSpaceModels, @@ -430,7 +474,7 @@ class SpaceManagementBloc String communityUuid, Emitter emit, ) async { - var prevSpaceModels = await fetchSpaceModels(previousState); + var prevSpaceModels = await fetchSpaceModels(); final communities = List.from(previousState.communities); @@ -629,7 +673,7 @@ class SpaceManagementBloc var spaceBloc = event.context.read(); List communities = spaceBloc.state.communityList; - var prevSpaceModels = await fetchSpaceModels(prevState); + var prevSpaceModels = await fetchSpaceModels(); if (communities.isEmpty) { communities = await _api.fetchCommunities(projectUuid); diff --git a/lib/pages/spaces_management/all_spaces/bloc/space_management_event.dart b/lib/pages/spaces_management/all_spaces/bloc/space_management_event.dart index 38e4bfb3..6bd685ba 100644 --- a/lib/pages/spaces_management/all_spaces/bloc/space_management_event.dart +++ b/lib/pages/spaces_management/all_spaces/bloc/space_management_event.dart @@ -1,7 +1,8 @@ import 'package:equatable/equatable.dart'; import 'package:flutter/material.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/community_model.dart'; -import 'package:syncrow_web/pages/spaces_management/all_spaces/model/space_model.dart'; // Import for Offset +import 'package:syncrow_web/pages/spaces_management/all_spaces/model/space_model.dart'; +import 'package:syncrow_web/pages/spaces_management/space_model/models/space_template_model.dart'; // Import for Offset abstract class SpaceManagementEvent extends Equatable { const SpaceManagementEvent(); @@ -160,3 +161,13 @@ class SpaceModelLoadEvent extends SpaceManagementEvent { @override List get props => [context]; } + +class UpdateSpaceModelCache extends SpaceManagementEvent { + final SpaceTemplateModel updatedModel; + UpdateSpaceModelCache(this.updatedModel); +} + +class DeleteSpaceModelFromCache extends SpaceManagementEvent { + final String deletedUuid; + DeleteSpaceModelFromCache(this.deletedUuid); +} \ No newline at end of file diff --git a/lib/pages/spaces_management/all_spaces/bloc/space_management_state.dart b/lib/pages/spaces_management/all_spaces/bloc/space_management_state.dart index 10a02294..674fce4c 100644 --- a/lib/pages/spaces_management/all_spaces/bloc/space_management_state.dart +++ b/lib/pages/spaces_management/all_spaces/bloc/space_management_state.dart @@ -71,3 +71,4 @@ class SpaceModelLoaded extends SpaceManagementState { @override List get props => [communities, products, spaceModels]; } + diff --git a/lib/pages/spaces_management/all_spaces/view/spaces_management_page.dart b/lib/pages/spaces_management/all_spaces/view/spaces_management_page.dart index 6c30e03b..b296eca8 100644 --- a/lib/pages/spaces_management/all_spaces/view/spaces_management_page.dart +++ b/lib/pages/spaces_management/all_spaces/view/spaces_management_page.dart @@ -3,6 +3,7 @@ import 'dart:developer'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:syncrow_web/pages/device_managment/shared/navigate_home_grid_view.dart'; +import 'package:syncrow_web/pages/space_tree/bloc/space_tree_bloc.dart'; import 'package:syncrow_web/pages/spaces_management/structure_selector/bloc/center_body_bloc.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/bloc/space_management_bloc.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/bloc/space_management_event.dart'; @@ -34,6 +35,7 @@ class SpaceManagementPageState extends State { _api, _productApi, _spaceModelApi, + BlocProvider.of(context), )..add(LoadCommunityAndSpacesEvent(this.context)), ), BlocProvider( From 6e90f81760338e0febd178fef09fe48e911862e0 Mon Sep 17 00:00:00 2001 From: hannathkadher Date: Wed, 5 Mar 2025 12:28:00 +0400 Subject: [PATCH 07/12] update space bloc on community and space change --- .env.development | 2 +- .../space_tree/bloc/space_tree_bloc.dart | 116 ++++++++++++------ .../space_tree/bloc/space_tree_event.dart | 9 ++ .../bloc/space_management_bloc.dart | 7 +- .../dialog/create_space_model_dialog.dart | 13 ++ .../widgets/space_model_card_widget.dart | 6 + 6 files changed, 114 insertions(+), 39 deletions(-) diff --git a/.env.development b/.env.development index e77609dc..1fd358ec 100644 --- a/.env.development +++ b/.env.development @@ -1,2 +1,2 @@ ENV_NAME=development -BASE_URL=https://syncrow-dev.azurewebsites.net \ No newline at end of file +BASE_URL=http://localhost:4001 \ No newline at end of file diff --git a/lib/pages/space_tree/bloc/space_tree_bloc.dart b/lib/pages/space_tree/bloc/space_tree_bloc.dart index 7820237b..31adaeb1 100644 --- a/lib/pages/space_tree/bloc/space_tree_bloc.dart +++ b/lib/pages/space_tree/bloc/space_tree_bloc.dart @@ -17,6 +17,32 @@ class SpaceTreeBloc extends Bloc { on(_clearAllData); on(_clearCachedData); on(_onCommunityAdded); + on(_onCommunityUpdate); + } + + void _onCommunityUpdate( + OnCommunityUpdated event, + Emitter emit, + ) async { + emit(SpaceTreeLoadingState()); + + try { + final updatedCommunity = event.updatedCommunity; + final updatedCommunities = + List.from(state.communityList); + + final index = updatedCommunities + .indexWhere((community) => community.uuid == updatedCommunity.uuid); + + if (index != -1) { + updatedCommunities[index] = updatedCommunity; + emit(state.copyWith(communitiesList: updatedCommunities)); + } else { + emit(SpaceTreeErrorState('Community not found in the list.')); + } + } catch (e) { + emit(SpaceTreeErrorState('Error updating community: $e')); + } } _fetchSpaces(InitialEvent event, Emitter emit) async { @@ -29,8 +55,8 @@ class SpaceTreeBloc extends Bloc { List updatedCommunities = await Future.wait( communities.map((community) async { - List spaces = - await CommunitySpaceManagementApi().getSpaceHierarchy(community.uuid, projectUuid); + List spaces = await CommunitySpaceManagementApi() + .getSpaceHierarchy(community.uuid, projectUuid); return CommunityModel( uuid: community.uuid, @@ -45,23 +71,27 @@ class SpaceTreeBloc extends Bloc { ); emit(state.copyWith( - communitiesList: updatedCommunities, expandedCommunity: [], expandedSpaces: [])); + communitiesList: updatedCommunities, + expandedCommunity: [], + expandedSpaces: [])); } catch (e) { emit(SpaceTreeErrorState('Error loading communities and spaces: $e')); } } - void _onCommunityAdded(OnCommunityAdded event, Emitter emit) async { - final updatedCommunities = List.from(state.communityList); - updatedCommunities.add(event.newCommunity); + void _onCommunityAdded( + OnCommunityAdded event, Emitter emit) async { + final updatedCommunities = List.from(state.communityList); + updatedCommunities.add(event.newCommunity); - emit(state.copyWith(communitiesList: updatedCommunities)); -} + emit(state.copyWith(communitiesList: updatedCommunities)); + } - - _onCommunityExpanded(OnCommunityExpanded event, Emitter emit) async { + _onCommunityExpanded( + OnCommunityExpanded event, Emitter emit) async { try { - List updatedExpandedCommunityList = List.from(state.expandedCommunities); + List updatedExpandedCommunityList = + List.from(state.expandedCommunities); if (updatedExpandedCommunityList.contains(event.communityId)) { updatedExpandedCommunityList.remove(event.communityId); @@ -93,14 +123,19 @@ class SpaceTreeBloc extends Bloc { } } - _onCommunitySelected(OnCommunitySelected event, Emitter emit) async { + _onCommunitySelected( + OnCommunitySelected event, Emitter emit) async { try { List updatedSelectedCommunities = List.from(state.selectedCommunities.toSet().toList()); - List updatedSelectedSpaces = List.from(state.selectedSpaces.toSet().toList()); - List updatedSoldChecks = List.from(state.soldCheck.toSet().toList()); - Map> communityAndSpaces = Map.from(state.selectedCommunityAndSpaces); - List selectedSpacesInCommunity = communityAndSpaces[event.communityId] ?? []; + List updatedSelectedSpaces = + List.from(state.selectedSpaces.toSet().toList()); + List updatedSoldChecks = + List.from(state.soldCheck.toSet().toList()); + Map> communityAndSpaces = + Map.from(state.selectedCommunityAndSpaces); + List selectedSpacesInCommunity = + communityAndSpaces[event.communityId] ?? []; List childrenIds = _getAllChildIds(event.children); @@ -133,11 +168,15 @@ class SpaceTreeBloc extends Bloc { try { List updatedSelectedCommunities = List.from(state.selectedCommunities.toSet().toList()); - List updatedSelectedSpaces = List.from(state.selectedSpaces.toSet().toList()); - List updatedSoldChecks = List.from(state.soldCheck.toSet().toList()); - Map> communityAndSpaces = Map.from(state.selectedCommunityAndSpaces); + List updatedSelectedSpaces = + List.from(state.selectedSpaces.toSet().toList()); + List updatedSoldChecks = + List.from(state.soldCheck.toSet().toList()); + Map> communityAndSpaces = + Map.from(state.selectedCommunityAndSpaces); - List selectedSpacesInCommunity = communityAndSpaces[event.communityModel.uuid] ?? []; + List selectedSpacesInCommunity = + communityAndSpaces[event.communityModel.uuid] ?? []; List childrenIds = _getAllChildIds(event.children); bool isChildSelected = false; @@ -160,9 +199,11 @@ class SpaceTreeBloc extends Bloc { selectedSpacesInCommunity.addAll(childrenIds); } - List spaces = _getThePathToChild(event.communityModel.uuid, event.spaceId); + List spaces = + _getThePathToChild(event.communityModel.uuid, event.spaceId); for (String space in spaces) { - if (!updatedSelectedSpaces.contains(space) && !updatedSoldChecks.contains(space)) { + if (!updatedSelectedSpaces.contains(space) && + !updatedSoldChecks.contains(space)) { updatedSoldChecks.add(space); } } @@ -185,7 +226,9 @@ class SpaceTreeBloc extends Bloc { updatedSoldChecks.remove(event.spaceId); List parents = - _getThePathToChild(event.communityModel.uuid, event.spaceId).toSet().toList(); + _getThePathToChild(event.communityModel.uuid, event.spaceId) + .toSet() + .toList(); if (updatedSelectedSpaces.isEmpty) { updatedSoldChecks.removeWhere(parents.contains); @@ -193,7 +236,8 @@ class SpaceTreeBloc extends Bloc { } else { // Check if any parent has selected children for (String space in parents) { - if (!_noChildrenSelected(event.communityModel, space, updatedSelectedSpaces, parents)) { + if (!_noChildrenSelected( + event.communityModel, space, updatedSelectedSpaces, parents)) { updatedSoldChecks.remove(space); } } @@ -218,8 +262,8 @@ class SpaceTreeBloc extends Bloc { } } - _noChildrenSelected( - CommunityModel community, String spaceId, List selectedSpaces, List parents) { + _noChildrenSelected(CommunityModel community, String spaceId, + List selectedSpaces, List parents) { if (selectedSpaces.contains(spaceId)) { return true; } @@ -246,10 +290,11 @@ class SpaceTreeBloc extends Bloc { // Filter communities and expand only those that match the query filteredCommunity = communities.where((community) { - final containsQueryInCommunity = - community.name.toLowerCase().contains(event.searchQuery.toLowerCase()); - final containsQueryInSpaces = - community.spaces.any((space) => _containsQuery(space, event.searchQuery.toLowerCase())); + final containsQueryInCommunity = community.name + .toLowerCase() + .contains(event.searchQuery.toLowerCase()); + final containsQueryInSpaces = community.spaces.any( + (space) => _containsQuery(space, event.searchQuery.toLowerCase())); return containsQueryInCommunity || containsQueryInSpaces; }).toList(); @@ -302,8 +347,8 @@ class SpaceTreeBloc extends Bloc { // Helper function to determine if any space or its children match the search query bool _containsQuery(SpaceModel space, String query) { final matchesSpace = space.name.toLowerCase().contains(query); - final matchesChildren = - space.children.any((child) => _containsQuery(child, query)); // Recursive check for children + final matchesChildren = space.children.any((child) => + _containsQuery(child, query)); // Recursive check for children return matchesSpace || matchesChildren; } @@ -326,8 +371,8 @@ class SpaceTreeBloc extends Bloc { return children; } - bool _anySpacesSelectedInCommunity( - CommunityModel community, List selectedSpaces, List partialCheckedList) { + bool _anySpacesSelectedInCommunity(CommunityModel community, + List selectedSpaces, List partialCheckedList) { bool result = false; List ids = _getAllChildIds(community.spaces); for (var id in ids) { @@ -356,7 +401,8 @@ class SpaceTreeBloc extends Bloc { return ids; } - List _getAllParentsIds(SpaceModel child, String spaceId, List listIds) { + List _getAllParentsIds( + SpaceModel child, String spaceId, List listIds) { List ids = listIds; ids.add(child.uuid ?? ''); diff --git a/lib/pages/space_tree/bloc/space_tree_event.dart b/lib/pages/space_tree/bloc/space_tree_event.dart index a22426f7..fdf1240b 100644 --- a/lib/pages/space_tree/bloc/space_tree_event.dart +++ b/lib/pages/space_tree/bloc/space_tree_event.dart @@ -77,6 +77,15 @@ class OnCommunityAdded extends SpaceTreeEvent { List get props => [newCommunity]; } +class OnCommunityUpdated extends SpaceTreeEvent { + final CommunityModel updatedCommunity; + const OnCommunityUpdated(this.updatedCommunity); + + @override + List get props => [updatedCommunity]; +} + + class ClearAllData extends SpaceTreeEvent {} class ClearCachedData extends SpaceTreeEvent {} diff --git a/lib/pages/spaces_management/all_spaces/bloc/space_management_bloc.dart b/lib/pages/spaces_management/all_spaces/bloc/space_management_bloc.dart index ddc294d7..7b62d0ac 100644 --- a/lib/pages/spaces_management/all_spaces/bloc/space_management_bloc.dart +++ b/lib/pages/spaces_management/all_spaces/bloc/space_management_bloc.dart @@ -139,7 +139,6 @@ class SpaceManagementBloc UpdateCommunityEvent event, Emitter emit, ) async { - final previousState = state; try { final projectUuid = await ProjectManager.getProjectUUID() ?? ''; @@ -154,6 +153,8 @@ class SpaceManagementBloc for (var community in updatedCommunities) { if (community.uuid == event.communityUuid) { community.name = event.name; + _spaceTreeBloc.add(OnCommunityAdded(community)); + break; } } @@ -456,8 +457,6 @@ class SpaceManagementBloc event.communityUuid, emit, ); - } else { - // add(LoadCommunityAndSpacesEvent()); } } catch (e) { emit(SpaceManagementError('Error saving spaces: $e')); @@ -481,6 +480,8 @@ class SpaceManagementBloc for (var community in communities) { if (community.uuid == communityUuid) { community.spaces = allSpaces; + _spaceTreeBloc.add(OnCommunityUpdated(community)); + emit(SpaceManagementLoaded( communities: communities, products: _cachedProducts ?? [], diff --git a/lib/pages/spaces_management/space_model/widgets/dialog/create_space_model_dialog.dart b/lib/pages/spaces_management/space_model/widgets/dialog/create_space_model_dialog.dart index 9a89c452..69e619b7 100644 --- a/lib/pages/spaces_management/space_model/widgets/dialog/create_space_model_dialog.dart +++ b/lib/pages/spaces_management/space_model/widgets/dialog/create_space_model_dialog.dart @@ -2,6 +2,8 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:syncrow_web/pages/common/buttons/cancel_button.dart'; import 'package:syncrow_web/pages/common/buttons/default_button.dart'; +import 'package:syncrow_web/pages/spaces_management/all_spaces/bloc/space_management_bloc.dart'; +import 'package:syncrow_web/pages/spaces_management/all_spaces/bloc/space_management_event.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/product_model.dart'; import 'package:syncrow_web/pages/spaces_management/space_model/bloc/create_space_model_bloc.dart'; import 'package:syncrow_web/pages/spaces_management/space_model/bloc/create_space_model_event.dart'; @@ -196,6 +198,12 @@ class CreateSpaceModelDialog extends StatelessWidget { .add(CreateSpaceModel( newSpaceModel: newModel)); + pageContext! + .read< + SpaceManagementBloc>() + .add( + UpdateSpaceModelCache( + newModel)); } Navigator.of(context) .pop(); // Close the dialog @@ -241,6 +249,11 @@ class CreateSpaceModelDialog extends StatelessWidget { spaceModelUuid: newModel.uuid ?? '')); + pageContext! + .read< + SpaceManagementBloc>() + .add(UpdateSpaceModelCache( + newModel)); } Navigator.of(context) .pop(); diff --git a/lib/pages/spaces_management/space_model/widgets/space_model_card_widget.dart b/lib/pages/spaces_management/space_model/widgets/space_model_card_widget.dart index ab65af44..692511cf 100644 --- a/lib/pages/spaces_management/space_model/widgets/space_model_card_widget.dart +++ b/lib/pages/spaces_management/space_model/widgets/space_model_card_widget.dart @@ -4,6 +4,8 @@ import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_svg/svg.dart'; import 'package:syncrow_web/pages/common/buttons/cancel_button.dart'; import 'package:syncrow_web/pages/common/buttons/default_button.dart'; +import 'package:syncrow_web/pages/spaces_management/all_spaces/bloc/space_management_bloc.dart'; +import 'package:syncrow_web/pages/spaces_management/all_spaces/bloc/space_management_event.dart'; import 'package:syncrow_web/pages/spaces_management/space_model/bloc/space_model_bloc.dart'; import 'package:syncrow_web/pages/spaces_management/space_model/bloc/space_model_event.dart'; @@ -182,6 +184,10 @@ class SpaceModelCardWidget extends StatelessWidget { pageContext!.read().add( DeleteSpaceModel(spaceModelUuid: model.uuid ?? ''), ); + + pageContext!.read().add( + DeleteSpaceModelFromCache(model.uuid ?? ''), + ); } }, ); From ef777cfce9b29ffa80ae41b558e9726111f1a634 Mon Sep 17 00:00:00 2001 From: hannathkadher Date: Wed, 5 Mar 2025 12:28:16 +0400 Subject: [PATCH 08/12] remove unused import --- .../space_model/widgets/space_model_card_widget.dart | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/pages/spaces_management/space_model/widgets/space_model_card_widget.dart b/lib/pages/spaces_management/space_model/widgets/space_model_card_widget.dart index 692511cf..f446695e 100644 --- a/lib/pages/spaces_management/space_model/widgets/space_model_card_widget.dart +++ b/lib/pages/spaces_management/space_model/widgets/space_model_card_widget.dart @@ -2,8 +2,6 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_svg/svg.dart'; -import 'package:syncrow_web/pages/common/buttons/cancel_button.dart'; -import 'package:syncrow_web/pages/common/buttons/default_button.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/bloc/space_management_bloc.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/bloc/space_management_event.dart'; import 'package:syncrow_web/pages/spaces_management/space_model/bloc/space_model_bloc.dart'; From 64adf516f683c23a6368d8c01fc4a58dad8efbd8 Mon Sep 17 00:00:00 2001 From: hannathkadher Date: Wed, 5 Mar 2025 12:28:53 +0400 Subject: [PATCH 09/12] revert back --- .env.development | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.env.development b/.env.development index 1fd358ec..e77609dc 100644 --- a/.env.development +++ b/.env.development @@ -1,2 +1,2 @@ ENV_NAME=development -BASE_URL=http://localhost:4001 \ No newline at end of file +BASE_URL=https://syncrow-dev.azurewebsites.net \ No newline at end of file From 45f6599c4072a7b6b942cef82c245a1ccf135514 Mon Sep 17 00:00:00 2001 From: hannathkadher Date: Thu, 6 Mar 2025 11:42:28 +0400 Subject: [PATCH 10/12] removed logs --- .../all_spaces/bloc/space_management_bloc.dart | 6 ------ 1 file changed, 6 deletions(-) diff --git a/lib/pages/spaces_management/all_spaces/bloc/space_management_bloc.dart b/lib/pages/spaces_management/all_spaces/bloc/space_management_bloc.dart index 7b62d0ac..afa99252 100644 --- a/lib/pages/spaces_management/all_spaces/bloc/space_management_bloc.dart +++ b/lib/pages/spaces_management/all_spaces/bloc/space_management_bloc.dart @@ -91,10 +91,6 @@ class SpaceManagementBloc )); } - void _logEvent(String eventName) { - log('Event Triggered: $eventName'); - } - void updateCachedSpaceModels(List updatedModels) { _cachedSpaceModels = List.from(updatedModels); } @@ -282,8 +278,6 @@ class SpaceManagementBloc LoadCommunityAndSpacesEvent event, Emitter emit, ) async { - _logEvent('LoadCommunityAndSpacesEvent'); - var spaceBloc = event.context.read(); _onloadProducts(); From de614d40a5ac159a4ef3686a4386c89142ccdf03 Mon Sep 17 00:00:00 2001 From: hannathkadher Date: Thu, 6 Mar 2025 11:43:18 +0400 Subject: [PATCH 11/12] removed unused import --- .../spaces_management/all_spaces/bloc/space_management_bloc.dart | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/pages/spaces_management/all_spaces/bloc/space_management_bloc.dart b/lib/pages/spaces_management/all_spaces/bloc/space_management_bloc.dart index afa99252..49fa5d72 100644 --- a/lib/pages/spaces_management/all_spaces/bloc/space_management_bloc.dart +++ b/lib/pages/spaces_management/all_spaces/bloc/space_management_bloc.dart @@ -1,5 +1,4 @@ import 'dart:async'; -import 'dart:developer'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:syncrow_web/pages/common/bloc/project_manager.dart'; import 'package:syncrow_web/pages/space_tree/bloc/space_tree_bloc.dart'; From 8d072ee6bbe02a2797113ec92e6cc79142bb1c74 Mon Sep 17 00:00:00 2001 From: hannathkadher Date: Thu, 6 Mar 2025 11:48:43 +0400 Subject: [PATCH 12/12] added left padding --- .../all_spaces/widgets/community_tile.dart | 22 ++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/lib/pages/spaces_management/all_spaces/widgets/community_tile.dart b/lib/pages/spaces_management/all_spaces/widgets/community_tile.dart index 69a723c0..9bd45671 100644 --- a/lib/pages/spaces_management/all_spaces/widgets/community_tile.dart +++ b/lib/pages/spaces_management/all_spaces/widgets/community_tile.dart @@ -21,15 +21,17 @@ class CommunityTile extends StatelessWidget { @override Widget build(BuildContext context) { - return CustomExpansionTile( - title: title, - initiallyExpanded: isExpanded, - isSelected: isSelected, - onExpansionChanged: (bool expanded) { - onExpansionChanged(title, expanded); - }, - onItemSelected: onItemSelected, - children: children ?? [], - ); + return Padding( + padding: const EdgeInsets.only(left: 16.0), + child: CustomExpansionTile( + title: title, + initiallyExpanded: isExpanded, + isSelected: isSelected, + onExpansionChanged: (bool expanded) { + onExpansionChanged(title, expanded); + }, + onItemSelected: onItemSelected, + children: children ?? [], + )); } }