From 7af8887d4f051df9328c04d969a01bad1d3a8df3 Mon Sep 17 00:00:00 2001 From: Faris Armoush Date: Mon, 21 Jul 2025 15:57:10 +0300 Subject: [PATCH 01/12] Add new API endpoint for reordering spaces in the community module. --- lib/utils/constants/api_const.dart | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/utils/constants/api_const.dart b/lib/utils/constants/api_const.dart index e99f4796..ca9bee58 100644 --- a/lib/utils/constants/api_const.dart +++ b/lib/utils/constants/api_const.dart @@ -41,6 +41,8 @@ abstract class ApiEndpoints { '/projects/{projectId}/communities/{communityId}/spaces/{spaceId}'; static const String getSpaceHierarchy = '/projects/{projectId}/communities/{communityId}/spaces'; + static const String reorderSpaces = + '/projects/{projectUuid}/communities/{communityUuid}/spaces/{parentSpaceUuid}/spaces/order'; // Community Module static const String createCommunity = '/projects/{projectId}/communities'; From c65f4a7fabfaaa7c2e1e4559870c6c700fcf6a98 Mon Sep 17 00:00:00 2001 From: Faris Armoush Date: Mon, 21 Jul 2025 15:57:20 +0300 Subject: [PATCH 02/12] Add ReorderSpacesParam and ReorderSpacesService for managing space reordering functionality. --- .../domain/params/reorder_spaces_param.dart | 17 +++++++++++++++++ .../domain/services/reorder_spaces_service.dart | 5 +++++ 2 files changed, 22 insertions(+) create mode 100644 lib/pages/space_management_v2/modules/reorder_spaces/domain/params/reorder_spaces_param.dart create mode 100644 lib/pages/space_management_v2/modules/reorder_spaces/domain/services/reorder_spaces_service.dart diff --git a/lib/pages/space_management_v2/modules/reorder_spaces/domain/params/reorder_spaces_param.dart b/lib/pages/space_management_v2/modules/reorder_spaces/domain/params/reorder_spaces_param.dart new file mode 100644 index 00000000..fc3dd5ba --- /dev/null +++ b/lib/pages/space_management_v2/modules/reorder_spaces/domain/params/reorder_spaces_param.dart @@ -0,0 +1,17 @@ +import 'package:equatable/equatable.dart'; +import 'package:syncrow_web/pages/spaces_management/all_spaces/model/space_model.dart'; + +class ReorderSpacesParam extends Equatable { + const ReorderSpacesParam({ + required this.spaces, + required this.communityUuid, + required this.parentSpaceUuid, + }); + + final List spaces; + final String communityUuid; + final String parentSpaceUuid; + + @override + List get props => [spaces, communityUuid, parentSpaceUuid]; +} diff --git a/lib/pages/space_management_v2/modules/reorder_spaces/domain/services/reorder_spaces_service.dart b/lib/pages/space_management_v2/modules/reorder_spaces/domain/services/reorder_spaces_service.dart new file mode 100644 index 00000000..46811fae --- /dev/null +++ b/lib/pages/space_management_v2/modules/reorder_spaces/domain/services/reorder_spaces_service.dart @@ -0,0 +1,5 @@ +import 'package:syncrow_web/pages/space_management_v2/modules/reorder_spaces/domain/params/reorder_spaces_param.dart'; + +abstract interface class ReorderSpacesService { + Future reorderSpaces(ReorderSpacesParam param); +} From 9bf715501baa3383a6a4c232f37fd46c953e6298 Mon Sep 17 00:00:00 2001 From: Faris Armoush Date: Mon, 21 Jul 2025 15:57:31 +0300 Subject: [PATCH 03/12] Implement ReorderSpacesService. --- .../remote_reorder_spaces_service.dart | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 lib/pages/space_management_v2/modules/reorder_spaces/data/services/remote_reorder_spaces_service.dart diff --git a/lib/pages/space_management_v2/modules/reorder_spaces/data/services/remote_reorder_spaces_service.dart b/lib/pages/space_management_v2/modules/reorder_spaces/data/services/remote_reorder_spaces_service.dart new file mode 100644 index 00000000..463b31ce --- /dev/null +++ b/lib/pages/space_management_v2/modules/reorder_spaces/data/services/remote_reorder_spaces_service.dart @@ -0,0 +1,35 @@ +import 'package:dio/dio.dart'; +import 'package:syncrow_web/pages/space_management_v2/modules/reorder_spaces/domain/params/reorder_spaces_param.dart'; +import 'package:syncrow_web/pages/space_management_v2/modules/reorder_spaces/domain/services/reorder_spaces_service.dart'; +import 'package:syncrow_web/services/api/api_exception.dart'; +import 'package:syncrow_web/services/api/http_service.dart'; +import 'package:syncrow_web/utils/constants/api_const.dart'; + +final class RemoteReorderSpacesService implements ReorderSpacesService { + RemoteReorderSpacesService(this._httpClient); + + final HTTPService _httpClient; + + @override + Future reorderSpaces(ReorderSpacesParam param) async { + try { + await _httpClient.post( + path: ApiEndpoints.reorderSpaces, + body: param, + expectedResponseModel: (json) => json, + ); + } on DioException catch (e) { + final message = e.response?.data as Map?; + throw APIException(_getErrorMessageFromBody(message)); + } catch (e) { + throw APIException(e.toString()); + } + } + + String _getErrorMessageFromBody(Map? body) { + if (body == null) return 'Failed to delete space'; + final error = body['error'] as Map?; + final errorMessage = error?['message'] as String? ?? ''; + return errorMessage; + } +} From a3a7937021636596d7b446f4eace0b583a16b979 Mon Sep 17 00:00:00 2001 From: Faris Armoush Date: Mon, 21 Jul 2025 16:14:03 +0300 Subject: [PATCH 04/12] Implemented `ReorderSpacesBloc`. --- .../bloc/reorder_spaces_bloc.dart | 35 +++++++++++++++++++ .../bloc/reorder_spaces_event.dart | 10 ++++++ .../bloc/reorder_spaces_state.dart | 29 +++++++++++++++ 3 files changed, 74 insertions(+) create mode 100644 lib/pages/space_management_v2/modules/reorder_spaces/presentation/bloc/reorder_spaces_bloc.dart create mode 100644 lib/pages/space_management_v2/modules/reorder_spaces/presentation/bloc/reorder_spaces_event.dart create mode 100644 lib/pages/space_management_v2/modules/reorder_spaces/presentation/bloc/reorder_spaces_state.dart diff --git a/lib/pages/space_management_v2/modules/reorder_spaces/presentation/bloc/reorder_spaces_bloc.dart b/lib/pages/space_management_v2/modules/reorder_spaces/presentation/bloc/reorder_spaces_bloc.dart new file mode 100644 index 00000000..ecd15898 --- /dev/null +++ b/lib/pages/space_management_v2/modules/reorder_spaces/presentation/bloc/reorder_spaces_bloc.dart @@ -0,0 +1,35 @@ +import 'package:bloc/bloc.dart'; +import 'package:equatable/equatable.dart'; +import 'package:syncrow_web/pages/space_management_v2/modules/reorder_spaces/domain/params/reorder_spaces_param.dart'; +import 'package:syncrow_web/pages/space_management_v2/modules/reorder_spaces/domain/services/reorder_spaces_service.dart'; +import 'package:syncrow_web/services/api/api_exception.dart'; + +part 'reorder_spaces_event.dart'; +part 'reorder_spaces_state.dart'; + +class ReorderSpacesBloc extends Bloc { + ReorderSpacesBloc( + this._reorderSpacesService, + ) : super(const ReorderSpacesInitial()) { + on(_onReorderSpacesEvent); + } + + final ReorderSpacesService _reorderSpacesService; + + Future _onReorderSpacesEvent( + ReorderSpacesEvent event, + Emitter emit, + ) async { + emit(const ReorderSpacesLoading()); + try { + await _reorderSpacesService.reorderSpaces(event.param); + emit(const ReorderSpacesSuccess()); + } on APIException catch (e) { + emit(ReorderSpacesFailure(e.message)); + } catch (e) { + emit(ReorderSpacesFailure(e.toString())); + } finally { + emit(const ReorderSpacesInitial()); + } + } +} diff --git a/lib/pages/space_management_v2/modules/reorder_spaces/presentation/bloc/reorder_spaces_event.dart b/lib/pages/space_management_v2/modules/reorder_spaces/presentation/bloc/reorder_spaces_event.dart new file mode 100644 index 00000000..8cccb4f1 --- /dev/null +++ b/lib/pages/space_management_v2/modules/reorder_spaces/presentation/bloc/reorder_spaces_event.dart @@ -0,0 +1,10 @@ +part of 'reorder_spaces_bloc.dart'; + +final class ReorderSpacesEvent extends Equatable { + const ReorderSpacesEvent(this.param); + + final ReorderSpacesParam param; + + @override + List get props => [param]; +} diff --git a/lib/pages/space_management_v2/modules/reorder_spaces/presentation/bloc/reorder_spaces_state.dart b/lib/pages/space_management_v2/modules/reorder_spaces/presentation/bloc/reorder_spaces_state.dart new file mode 100644 index 00000000..d237d93c --- /dev/null +++ b/lib/pages/space_management_v2/modules/reorder_spaces/presentation/bloc/reorder_spaces_state.dart @@ -0,0 +1,29 @@ +part of 'reorder_spaces_bloc.dart'; + +sealed class ReorderSpacesState extends Equatable { + const ReorderSpacesState(); + + @override + List get props => []; +} + +final class ReorderSpacesInitial extends ReorderSpacesState { + const ReorderSpacesInitial(); +} + +final class ReorderSpacesLoading extends ReorderSpacesState { + const ReorderSpacesLoading(); +} + +final class ReorderSpacesSuccess extends ReorderSpacesState { + const ReorderSpacesSuccess(); +} + +final class ReorderSpacesFailure extends ReorderSpacesState { + const ReorderSpacesFailure(this.errorMessage); + + final String errorMessage; + + @override + List get props => [errorMessage]; +} From 96f107f97208012b1fe1301758882057dd3fec36 Mon Sep 17 00:00:00 2001 From: Faris Armoush Date: Mon, 21 Jul 2025 16:15:26 +0300 Subject: [PATCH 05/12] Refactor SpaceManagementPage to utilize a shared HTTPService instance for API calls in `Communities`, `SpaceDetails`, `Products`, and `ReorderSpaces` blocs, and injected `ReorderSpacesBloc` into it. --- .../main_module/views/space_management_page.dart | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/lib/pages/space_management_v2/main_module/views/space_management_page.dart b/lib/pages/space_management_v2/main_module/views/space_management_page.dart index 55e47de1..5c226671 100644 --- a/lib/pages/space_management_v2/main_module/views/space_management_page.dart +++ b/lib/pages/space_management_v2/main_module/views/space_management_page.dart @@ -9,6 +9,8 @@ import 'package:syncrow_web/pages/space_management_v2/modules/communities/presen import 'package:syncrow_web/pages/space_management_v2/modules/communities/presentation/communities_tree_selection_bloc/communities_tree_selection_bloc.dart'; import 'package:syncrow_web/pages/space_management_v2/modules/products/data/services/remote_products_service.dart'; import 'package:syncrow_web/pages/space_management_v2/modules/products/presentation/bloc/products_bloc.dart'; +import 'package:syncrow_web/pages/space_management_v2/modules/reorder_spaces/data/services/remote_reorder_spaces_service.dart'; +import 'package:syncrow_web/pages/space_management_v2/modules/reorder_spaces/presentation/bloc/reorder_spaces_bloc.dart'; import 'package:syncrow_web/pages/space_management_v2/modules/space_details/data/services/remote_space_details_service.dart'; import 'package:syncrow_web/pages/space_management_v2/modules/space_details/data/services/unique_space_details_spaces_decorator_service.dart'; import 'package:syncrow_web/pages/space_management_v2/modules/space_details/presentation/bloc/space_details_bloc.dart'; @@ -25,15 +27,16 @@ class SpaceManagementPage extends StatefulWidget { class _SpaceManagementPageState extends State { late final CommunitiesBloc communitiesBloc; + late final HTTPService _httpService; @override void initState() { communitiesBloc = CommunitiesBloc( communitiesService: DebouncedCommunitiesService( - RemoteCommunitiesService(HTTPService()), + RemoteCommunitiesService(_httpService), ), )..add(const LoadCommunities(LoadCommunitiesParam())); - + _httpService = HTTPService(); super.initState(); } @@ -50,13 +53,18 @@ class _SpaceManagementPageState extends State { BlocProvider( create: (context) => SpaceDetailsBloc( UniqueSpaceDetailsSpacesDecoratorService( - RemoteSpaceDetailsService(httpService: HTTPService()), + RemoteSpaceDetailsService(httpService: _httpService), ), ), ), BlocProvider( create: (context) => ProductsBloc( - RemoteProductsService(HTTPService()), + RemoteProductsService(_httpService), + ), + ), + BlocProvider( + create: (context) => ReorderSpacesBloc( + RemoteReorderSpacesService(_httpService), ), ), ], From 35c8a73156414f15835bded948ceb8f8697656c2 Mon Sep 17 00:00:00 2001 From: Faris Armoush Date: Mon, 21 Jul 2025 16:24:11 +0300 Subject: [PATCH 06/12] Refactor SpaceManagementPage's initState to ensure HTTPService is initialized before use in CommunitiesBloc. --- .../main_module/views/space_management_page.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/pages/space_management_v2/main_module/views/space_management_page.dart b/lib/pages/space_management_v2/main_module/views/space_management_page.dart index 5c226671..47a67c36 100644 --- a/lib/pages/space_management_v2/main_module/views/space_management_page.dart +++ b/lib/pages/space_management_v2/main_module/views/space_management_page.dart @@ -31,12 +31,12 @@ class _SpaceManagementPageState extends State { @override void initState() { + _httpService = HTTPService(); communitiesBloc = CommunitiesBloc( communitiesService: DebouncedCommunitiesService( RemoteCommunitiesService(_httpService), ), )..add(const LoadCommunities(LoadCommunitiesParam())); - _httpService = HTTPService(); super.initState(); } From 1323bceca12a82b1a7b1f19e677d4786ddf44294 Mon Sep 17 00:00:00 2001 From: Faris Armoush Date: Mon, 21 Jul 2025 16:39:31 +0300 Subject: [PATCH 07/12] Update ReorderSpacesParam to make parentSpaceUuid optional and add toJson method for serialization. --- .../domain/params/reorder_spaces_param.dart | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/lib/pages/space_management_v2/modules/reorder_spaces/domain/params/reorder_spaces_param.dart b/lib/pages/space_management_v2/modules/reorder_spaces/domain/params/reorder_spaces_param.dart index fc3dd5ba..e18544a8 100644 --- a/lib/pages/space_management_v2/modules/reorder_spaces/domain/params/reorder_spaces_param.dart +++ b/lib/pages/space_management_v2/modules/reorder_spaces/domain/params/reorder_spaces_param.dart @@ -1,17 +1,21 @@ import 'package:equatable/equatable.dart'; -import 'package:syncrow_web/pages/spaces_management/all_spaces/model/space_model.dart'; +import 'package:syncrow_web/pages/space_management_v2/modules/communities/domain/models/space_model.dart'; class ReorderSpacesParam extends Equatable { const ReorderSpacesParam({ required this.spaces, required this.communityUuid, - required this.parentSpaceUuid, + this.parentSpaceUuid, }); final List spaces; final String communityUuid; - final String parentSpaceUuid; + final String? parentSpaceUuid; @override List get props => [spaces, communityUuid, parentSpaceUuid]; + + Map toJson() => { + 'spacesUuids': spaces.map((space) => space.uuid).toList(), + }; } From 40251b846b79eca48f42eb774e85b8ad64ed69f2 Mon Sep 17 00:00:00 2001 From: Faris Armoush Date: Mon, 21 Jul 2025 16:43:26 +0300 Subject: [PATCH 08/12] Integrate ReorderSpaces functionality into CommunityStructureCanvas and enhance RemoteReorderSpacesService with dynamic URL generation. Update ReorderSpacesParam to require parentSpaceUuid and spaces for improved validation and serialization. --- .../widgets/community_structure_canvas.dart | 12 +++++++++ .../remote_reorder_spaces_service.dart | 27 +++++++++++++++++-- .../domain/params/reorder_spaces_param.dart | 8 +++--- 3 files changed, 41 insertions(+), 6 deletions(-) diff --git a/lib/pages/space_management_v2/main_module/widgets/community_structure_canvas.dart b/lib/pages/space_management_v2/main_module/widgets/community_structure_canvas.dart index 692ffc0a..e07bd4a4 100644 --- a/lib/pages/space_management_v2/main_module/widgets/community_structure_canvas.dart +++ b/lib/pages/space_management_v2/main_module/widgets/community_structure_canvas.dart @@ -11,6 +11,8 @@ import 'package:syncrow_web/pages/space_management_v2/modules/communities/domain import 'package:syncrow_web/pages/space_management_v2/modules/communities/domain/models/space_model.dart'; import 'package:syncrow_web/pages/space_management_v2/modules/communities/presentation/bloc/communities_bloc.dart'; import 'package:syncrow_web/pages/space_management_v2/modules/communities/presentation/communities_tree_selection_bloc/communities_tree_selection_bloc.dart'; +import 'package:syncrow_web/pages/space_management_v2/modules/reorder_spaces/domain/params/reorder_spaces_param.dart'; +import 'package:syncrow_web/pages/space_management_v2/modules/reorder_spaces/presentation/bloc/reorder_spaces_bloc.dart'; import 'package:syncrow_web/pages/space_management_v2/modules/space_details/presentation/helpers/space_details_dialog_helper.dart'; import 'package:syncrow_web/utils/extension/build_context_x.dart'; @@ -164,6 +166,16 @@ class _CommunityStructureCanvasState extends State context.read().add( CommunitiesUpdateCommunity(newCommunity), ); + + context.read().add( + ReorderSpacesEvent( + ReorderSpacesParam( + communityUuid: widget.community.uuid, + parentSpaceUuid: data.parent?.uuid ?? '', + spaces: children, + ), + ), + ); } void _onSpaceTapped(SpaceModel? space) { diff --git a/lib/pages/space_management_v2/modules/reorder_spaces/data/services/remote_reorder_spaces_service.dart b/lib/pages/space_management_v2/modules/reorder_spaces/data/services/remote_reorder_spaces_service.dart index 463b31ce..c2494c09 100644 --- a/lib/pages/space_management_v2/modules/reorder_spaces/data/services/remote_reorder_spaces_service.dart +++ b/lib/pages/space_management_v2/modules/reorder_spaces/data/services/remote_reorder_spaces_service.dart @@ -1,4 +1,5 @@ import 'package:dio/dio.dart'; +import 'package:syncrow_web/pages/common/bloc/project_manager.dart'; import 'package:syncrow_web/pages/space_management_v2/modules/reorder_spaces/domain/params/reorder_spaces_param.dart'; import 'package:syncrow_web/pages/space_management_v2/modules/reorder_spaces/domain/services/reorder_spaces_service.dart'; import 'package:syncrow_web/services/api/api_exception.dart'; @@ -14,8 +15,8 @@ final class RemoteReorderSpacesService implements ReorderSpacesService { Future reorderSpaces(ReorderSpacesParam param) async { try { await _httpClient.post( - path: ApiEndpoints.reorderSpaces, - body: param, + path: await _makeUrl(param), + body: param.toJson(), expectedResponseModel: (json) => json, ); } on DioException catch (e) { @@ -32,4 +33,26 @@ final class RemoteReorderSpacesService implements ReorderSpacesService { final errorMessage = error?['message'] as String? ?? ''; return errorMessage; } + + Future _makeUrl(ReorderSpacesParam param) async { + final projectUuid = await ProjectManager.getProjectUUID(); + final communityUuid = param.communityUuid; + + if (projectUuid == null || projectUuid.isEmpty) { + throw APIException('Project UUID is not set'); + } + + if (communityUuid.isEmpty) { + throw APIException('Community UUID is not set'); + } + + if (param.parentSpaceUuid.isEmpty) { + throw APIException('Parent Space UUID is not set'); + } + + return ApiEndpoints.reorderSpaces + .replaceAll('{projectUuid}', projectUuid) + .replaceAll('{communityUuid}', communityUuid) + .replaceAll('{parentSpaceUuid}', param.parentSpaceUuid); + } } diff --git a/lib/pages/space_management_v2/modules/reorder_spaces/domain/params/reorder_spaces_param.dart b/lib/pages/space_management_v2/modules/reorder_spaces/domain/params/reorder_spaces_param.dart index e18544a8..05316006 100644 --- a/lib/pages/space_management_v2/modules/reorder_spaces/domain/params/reorder_spaces_param.dart +++ b/lib/pages/space_management_v2/modules/reorder_spaces/domain/params/reorder_spaces_param.dart @@ -3,14 +3,14 @@ import 'package:syncrow_web/pages/space_management_v2/modules/communities/domain class ReorderSpacesParam extends Equatable { const ReorderSpacesParam({ - required this.spaces, required this.communityUuid, - this.parentSpaceUuid, + required this.parentSpaceUuid, + required this.spaces, }); - final List spaces; final String communityUuid; - final String? parentSpaceUuid; + final String parentSpaceUuid; + final List spaces; @override List get props => [spaces, communityUuid, parentSpaceUuid]; From 9d60f913ebbbf85805813310fff4b8bfd3a73833 Mon Sep 17 00:00:00 2001 From: Faris Armoush Date: Tue, 22 Jul 2025 09:32:57 +0300 Subject: [PATCH 09/12] Refactor CommunityStructureCanvas to simplify DragTarget logic by replacing SizedBox with SizedBox.shrink() for better performance and readability. --- .../main_module/widgets/community_structure_canvas.dart | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/lib/pages/space_management_v2/main_module/widgets/community_structure_canvas.dart b/lib/pages/space_management_v2/main_module/widgets/community_structure_canvas.dart index e07bd4a4..a4d941bc 100644 --- a/lib/pages/space_management_v2/main_module/widgets/community_structure_canvas.dart +++ b/lib/pages/space_management_v2/main_module/widgets/community_structure_canvas.dart @@ -425,18 +425,14 @@ class _CommunityStructureCanvasState extends State height: _cardHeight, child: DragTarget( builder: (context, candidateData, rejectedData) { - if (_draggedData == null) { - return const SizedBox(); - } + if (_draggedData == null) return const SizedBox.shrink(); final isTargetForDragged = (_draggedData?.parent?.uuid == parent?.uuid && _draggedData?.community == null) || (_draggedData?.community?.uuid == community?.uuid && _draggedData?.parent == null); - if (!isTargetForDragged) { - return const SizedBox(); - } + if (!isTargetForDragged) return const SizedBox.shrink(); return Container( width: 40, From 60b8ee8b5036623fd57ecc95d7b312a50bc371d8 Mon Sep 17 00:00:00 2001 From: Faris Armoush Date: Tue, 22 Jul 2025 09:37:31 +0300 Subject: [PATCH 10/12] Enhance DragTarget logic in CommunityStructureCanvas by refining conditions for rendering and improving readability. Ensure proper handling of dragged data and its parent/community relationships. --- .../widgets/community_structure_canvas.dart | 27 ++++++++++++++----- 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/lib/pages/space_management_v2/main_module/widgets/community_structure_canvas.dart b/lib/pages/space_management_v2/main_module/widgets/community_structure_canvas.dart index a4d941bc..37fa027b 100644 --- a/lib/pages/space_management_v2/main_module/widgets/community_structure_canvas.dart +++ b/lib/pages/space_management_v2/main_module/widgets/community_structure_canvas.dart @@ -425,17 +425,29 @@ class _CommunityStructureCanvasState extends State height: _cardHeight, child: DragTarget( builder: (context, candidateData, rejectedData) { - if (_draggedData == null) return const SizedBox.shrink(); + if (_draggedData == null) { + return const SizedBox.shrink(); + } - final isTargetForDragged = (_draggedData?.parent?.uuid == parent?.uuid && - _draggedData?.community == null) || - (_draggedData?.community?.uuid == community?.uuid && - _draggedData?.parent == null); + final children = parent?.children ?? community?.spaces ?? []; + final isSameParent = (_draggedData!.parent?.uuid == parent?.uuid && + _draggedData!.community == null) || + (_draggedData!.community?.uuid == community?.uuid && + _draggedData!.parent == null); - if (!isTargetForDragged) return const SizedBox.shrink(); + if (!isSameParent) { + return const SizedBox.shrink(); + } + + final oldIndex = + children.indexWhere((s) => s.uuid == _draggedData!.space.uuid); + if (oldIndex != -1 && (oldIndex == index || oldIndex == index - 1)) { + return const SizedBox.shrink(); + } return Container( width: 40, + alignment: Alignment.center, height: _cardHeight, decoration: BoxDecoration( color: context.theme.colorScheme.primary.withValues( @@ -462,6 +474,9 @@ class _CommunityStructureCanvasState extends State final oldIndex = children.indexWhere((s) => s.uuid == data.data.space.uuid); + if (oldIndex == -1) { + return true; + } if (oldIndex == index || oldIndex == index - 1) { return false; } From dfd8c5fa317c4e9230df4e69db4cf6817781b382 Mon Sep 17 00:00:00 2001 From: Faris Armoush Date: Tue, 22 Jul 2025 09:46:56 +0300 Subject: [PATCH 11/12] Replace Container with AnimatedContainer in CommunityStructureCanvas to enhance visual feedback during state changes. Adjust alpha value for improved visibility based on candidate data presence. --- .../main_module/widgets/community_structure_canvas.dart | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/pages/space_management_v2/main_module/widgets/community_structure_canvas.dart b/lib/pages/space_management_v2/main_module/widgets/community_structure_canvas.dart index 37fa027b..1d4b3e10 100644 --- a/lib/pages/space_management_v2/main_module/widgets/community_structure_canvas.dart +++ b/lib/pages/space_management_v2/main_module/widgets/community_structure_canvas.dart @@ -445,13 +445,14 @@ class _CommunityStructureCanvasState extends State return const SizedBox.shrink(); } - return Container( + return AnimatedContainer( + duration: const Duration(milliseconds: 150), width: 40, alignment: Alignment.center, height: _cardHeight, decoration: BoxDecoration( color: context.theme.colorScheme.primary.withValues( - alpha: candidateData.isNotEmpty ? 0.7 : 0.3, + alpha: candidateData.isNotEmpty ? 0.9 : 0.3, ), borderRadius: BorderRadius.circular(8), ), From 94f9c1beea313d707d40d88a9fa82540f452d14f Mon Sep 17 00:00:00 2001 From: Faris Armoush Date: Tue, 22 Jul 2025 10:04:38 +0300 Subject: [PATCH 12/12] Adjust layout in CommunityStructureCanvas by adding horizontal padding to positions and refining target position calculations for improved spacing and alignment. Enhance Stack widget behavior by allowing overflow clipping. --- .../widgets/community_structure_canvas.dart | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/lib/pages/space_management_v2/main_module/widgets/community_structure_canvas.dart b/lib/pages/space_management_v2/main_module/widgets/community_structure_canvas.dart index 1d4b3e10..6614aa88 100644 --- a/lib/pages/space_management_v2/main_module/widgets/community_structure_canvas.dart +++ b/lib/pages/space_management_v2/main_module/widgets/community_structure_canvas.dart @@ -257,6 +257,13 @@ class _CommunityStructureCanvasState extends State final levelXOffset = {}; _calculateLayout(community.spaces, 0, levelXOffset); + const horizontalCanvasPadding = 100.0; + final originalPositions = Map.of(_positions); + _positions.clear(); + for (final entry in originalPositions.entries) { + _positions[entry.key] = entry.value.translate(horizontalCanvasPadding, 0); + } + final selectedSpace = widget.selectedSpace; final highlightedUuids = {}; if (selectedSpace != null) { @@ -274,7 +281,7 @@ class _CommunityStructureCanvasState extends State community: widget.community, ); - final createButtonX = levelXOffset[0] ?? 0.0; + final createButtonX = (levelXOffset[0] ?? 0.0) + horizontalCanvasPadding; const createButtonY = 0.0; widgets.add( @@ -306,10 +313,12 @@ class _CommunityStructureCanvasState extends State CommunityModel? community, SpaceModel? parent, }) { + const targetWidth = 40.0; + final padding = (_horizontalSpacing - targetWidth) / 2; if (spaces.isNotEmpty) { final firstChildPos = _positions[spaces.first.uuid]!; final targetPos = Offset( - firstChildPos.dx - (_horizontalSpacing / 4), + firstChildPos.dx - padding - targetWidth, firstChildPos.dy, ); widgets.add(_buildDropTarget(parent, community, 0, targetPos)); @@ -391,7 +400,7 @@ class _CommunityStructureCanvasState extends State ); final targetPos = Offset( - position.dx + cardWidth + (_horizontalSpacing / 4) - 20, + position.dx + cardWidth + padding, position.dy, ); widgets.add(_buildDropTarget(parent, community, i + 1, targetPos)); @@ -505,7 +514,7 @@ class _CommunityStructureCanvasState extends State child: SizedBox( width: context.screenWidth * 5, height: context.screenHeight * 5, - child: Stack(children: treeWidgets), + child: Stack(clipBehavior: Clip.none, children: treeWidgets), ), ), );