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 759cea27..04087257 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 @@ -21,7 +21,8 @@ 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' as custom_action; -class SpaceManagementBloc extends Bloc { +class SpaceManagementBloc + extends Bloc { final CommunitySpaceManagementApi _api; final ProductApi _productApi; final SpaceModelManagementApi _spaceModelApi; @@ -62,7 +63,8 @@ class SpaceManagementBloc extends Bloc emit) async { + void _deleteSpaceModelFromCache(DeleteSpaceModelFromCache event, + Emitter emit) async { if (_cachedSpaceModels != null) { - _cachedSpaceModels = - _cachedSpaceModels!.where((model) => model.uuid != event.deletedUuid).toList(); + _cachedSpaceModels = _cachedSpaceModels! + .where((model) => model.uuid != event.deletedUuid) + .toList(); } else { _cachedSpaceModels = await fetchSpaceModels(); } await fetchTags(); emit(SpaceModelLoaded( - communities: - state is SpaceManagementLoaded ? (state as SpaceManagementLoaded).communities : [], + communities: state is SpaceManagementLoaded + ? (state as SpaceManagementLoaded).communities + : [], products: _cachedProducts ?? [], spaceModels: List.from(_cachedSpaceModels ?? []), allTags: _cachedTags ?? [])); @@ -122,8 +127,8 @@ class SpaceManagementBloc extends Bloc.from(previousState.communities); + final updatedCommunities = + List.from(previousState.communities); for (var community in updatedCommunities) { if (community.uuid == event.communityUuid) { community.name = event.name; @@ -212,7 +219,8 @@ class SpaceManagementBloc extends Bloc> _fetchSpacesForCommunity(String communityUuid) async { + Future> _fetchSpacesForCommunity( + String communityUuid) async { final projectUuid = await ProjectManager.getProjectUUID() ?? ''; return await _api.getSpaceHierarchy(communityUuid, projectUuid); @@ -242,20 +250,23 @@ class SpaceManagementBloc extends Bloc _onBlankState(BlankStateEvent event, Emitter emit) async { + Future _onBlankState( + BlankStateEvent event, Emitter emit) async { try { final previousState = state; final projectUuid = await ProjectManager.getProjectUUID() ?? ''; var spaceBloc = event.context.read(); var spaceTreeState = event.context.read().state; - List communities = await _waitForCommunityList(spaceBloc, spaceTreeState); + List communities = + await _waitForCommunityList(spaceBloc, spaceTreeState); await fetchSpaceModels(); await fetchTags(); var prevSpaceModels = await fetchSpaceModels(); - if (previousState is SpaceManagementLoaded || previousState is BlankState) { + if (previousState is SpaceManagementLoaded || + previousState is BlankState) { final prevCommunities = (previousState as dynamic).communities ?? []; emit(BlankState( communities: List.from(prevCommunities), @@ -286,7 +297,8 @@ class SpaceManagementBloc extends Bloc communities = await _waitForCommunityList(spaceBloc, spaceTreeState); + List communities = + await _waitForCommunityList(spaceBloc, spaceTreeState); // Fetch space models after communities are available final prevSpaceModels = await fetchSpaceModels(); @@ -310,8 +322,9 @@ class SpaceManagementBloc extends Bloc>(); final subscription = spaceBloc.stream.listen((state) { if (!completer.isCompleted && state.communityList.isNotEmpty) { - completer - .complete(state.searchQuery.isNotEmpty ? state.filteredCommunity : state.communityList); + completer.complete(state.searchQuery.isNotEmpty + ? state.filteredCommunity + : state.communityList); } }); try { @@ -339,7 +352,8 @@ class SpaceManagementBloc extends Bloc.from( (previousState as dynamic).communities, ); @@ -459,8 +474,8 @@ class SpaceManagementBloc extends Bloc().state; - final updatedSpaces = - await saveSpacesHierarchically(event.context, event.spaces, event.communityUuid); + final updatedSpaces = await saveSpacesHierarchically( + event.context, event.spaces, event.communityUuid); final allSpaces = await _fetchSpacesForCommunity(event.communityUuid); emit(SpaceCreationSuccess(spaces: updatedSpaces)); @@ -520,8 +535,8 @@ class SpaceManagementBloc extends Bloc> saveSpacesHierarchically( - BuildContext context, List spaces, String communityUuid) async { + Future> saveSpacesHierarchically(BuildContext context, + List spaces, String communityUuid) async { final orderedSpaces = flattenHierarchy(spaces); final projectUuid = await ProjectManager.getProjectUUID() ?? ''; @@ -575,17 +590,19 @@ class SpaceManagementBloc extends Bloc subspace.uuid == prevSubspace.uuid); + final existsInNew = newSubspaces + .any((subspace) => subspace.uuid == prevSubspace.uuid); if (!existsInNew) { subspaceUpdates.add(UpdateSubspaceTemplateModel( - action: custom_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: custom_action.Action.delete, uuid: prevSubspace.uuid)); + action: custom_action.Action.delete, + uuid: prevSubspace.uuid)); } } @@ -613,7 +630,9 @@ class SpaceManagementBloc extends Bloc tag.toCreateTagBodyModel()).toList() ?? []; + final tagBodyModels = subspace.tags + ?.map((tag) => tag.toCreateTagBodyModel()) + .toList() ?? + []; return CreateSubspaceModel() ..subspaceName = subspace.subspaceName ..tags = tagBodyModels; @@ -671,7 +691,6 @@ class SpaceManagementBloc extends Bloc emit) async { + void _onLoadSpaceModel( + SpaceModelLoadEvent event, Emitter emit) async { emit(SpaceManagementLoading()); try { @@ -757,14 +777,17 @@ class SpaceManagementBloc extends Bloc newTag.uuid == prevTag.uuid); + final existsInNew = + newTags.any((newTag) => newTag.uuid == prevTag.uuid); if (!existsInNew) { - tagUpdates.add(TagModelUpdate(action: custom_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: custom_action.Action.delete, uuid: prevTag.uuid)); + tagUpdates.add(TagModelUpdate( + action: custom_action.Action.delete, uuid: prevTag.uuid)); } } @@ -807,15 +830,16 @@ class SpaceManagementBloc extends Bloc findMatchingSpaces(List spaces, String targetUuid) { + List findMatchingSpaces( + List spaces, String targetUuid) { List matched = []; for (var space in spaces) { if (space.uuid == targetUuid) { matched.add(space); } - matched - .addAll(findMatchingSpaces(space.children, targetUuid)); // Recursively search in children + matched.addAll(findMatchingSpaces( + space.children, targetUuid)); // Recursively search in children } return matched; diff --git a/lib/pages/spaces_management/all_spaces/model/connection_model.dart b/lib/pages/spaces_management/all_spaces/model/connection_model.dart index a774efe2..0799d81e 100644 --- a/lib/pages/spaces_management/all_spaces/model/connection_model.dart +++ b/lib/pages/spaces_management/all_spaces/model/connection_model.dart @@ -3,23 +3,26 @@ import 'package:syncrow_web/pages/spaces_management/all_spaces/model/space_model class Connection { final SpaceModel startSpace; final SpaceModel endSpace; - final String direction; - Connection({required this.startSpace, required this.endSpace, required this.direction}); + Connection({ + required this.startSpace, + required this.endSpace, + }); Map toMap() { return { - 'startUuid': startSpace.uuid ?? 'unsaved-start-space-${startSpace.name}', // Fallback for unsaved spaces - 'endUuid': endSpace.uuid ?? 'unsaved-end-space-${endSpace.name}', // Fallback for unsaved spaces - 'direction': direction, + 'startUuid': startSpace.uuid ?? + 'unsaved-start-space-${startSpace.name}', // Fallback for unsaved spaces + 'endUuid': endSpace.uuid ?? + 'unsaved-end-space-${endSpace.name}', // Fallback for unsaved spaces }; } - static Connection fromMap(Map map, Map spaces) { + static Connection fromMap( + Map map, Map spaces) { return Connection( startSpace: spaces[map['startUuid']]!, endSpace: spaces[map['endUuid']]!, - direction: map['direction'], ); } } diff --git a/lib/pages/spaces_management/all_spaces/model/space_model.dart b/lib/pages/spaces_management/all_spaces/model/space_model.dart index 6e744a29..6b570004 100644 --- a/lib/pages/spaces_management/all_spaces/model/space_model.dart +++ b/lib/pages/spaces_management/all_spaces/model/space_model.dart @@ -116,7 +116,7 @@ class SpaceModel { instance.incomingConnection = Connection( startSpace: instance.parent ?? instance, // Parent space endSpace: instance, // This space instance - direction: conn['direction'], + ); } diff --git a/lib/pages/spaces_management/all_spaces/widgets/community_structure_widget.dart b/lib/pages/spaces_management/all_spaces/widgets/community_structure_widget.dart index 16ecae36..178f7659 100644 --- a/lib/pages/spaces_management/all_spaces/widgets/community_structure_widget.dart +++ b/lib/pages/spaces_management/all_spaces/widgets/community_structure_widget.dart @@ -199,13 +199,11 @@ class _CommunityStructureAreaState extends State { top: entry.value.position.dy, child: SpaceCardWidget( index: entry.key, - onButtonTap: (int index, Offset newPosition, - String direction) { + onButtonTap: (int index, Offset newPosition) { _showCreateSpaceDialog(screenSize, position: spaces[index].position + newPosition, parentIndex: index, - direction: direction, projectTags: widget.projectTags); }, position: entry.value.position, @@ -296,7 +294,6 @@ class _CommunityStructureAreaState extends State { void _showCreateSpaceDialog(Size screenSize, {Offset? position, int? parentIndex, - String? direction, double? canvasWidth, double? canvasHeight, required List projectTags}) { @@ -338,14 +335,13 @@ class _CommunityStructureAreaState extends State { subspaces: subspaces, tags: tags); - if (parentIndex != null && direction != null) { + if (parentIndex != null) { SpaceModel parentSpace = spaces[parentIndex]; parentSpace.internalId = spaces[parentIndex].internalId; newSpace.parent = parentSpace; final newConnection = Connection( startSpace: parentSpace, endSpace: newSpace, - direction: direction, ); connections.add(newConnection); newSpace.incomingConnection = newConnection; @@ -467,7 +463,6 @@ class _CommunityStructureAreaState extends State { Connection( startSpace: parent, endSpace: child, - direction: "down", ), ); @@ -750,7 +745,6 @@ class _CommunityStructureAreaState extends State { final newConnection = Connection( startSpace: parent, endSpace: duplicated, - direction: "down", ); connections.add(newConnection); duplicated.incomingConnection = newConnection; @@ -786,7 +780,6 @@ class _CommunityStructureAreaState extends State { final newConnection = Connection( startSpace: newSpace, endSpace: duplicatedChild, - direction: "down", ); connections.add(newConnection); diff --git a/lib/pages/spaces_management/all_spaces/widgets/curved_line_painter.dart b/lib/pages/spaces_management/all_spaces/widgets/curved_line_painter.dart index 2b85acfd..d8291110 100644 --- a/lib/pages/spaces_management/all_spaces/widgets/curved_line_painter.dart +++ b/lib/pages/spaces_management/all_spaces/widgets/curved_line_painter.dart @@ -30,28 +30,13 @@ class CurvedLinePainter extends CustomPainter { Offset end = connection.endSpace.position + const Offset(75, 0); // Center top of end space - if (connection.direction == 'down') { - // Curved line for down connections - final controlPoint = Offset((start.dx + end.dx) / 2, start.dy + 50); - final path = Path() - ..moveTo(start.dx, start.dy) - ..quadraticBezierTo(controlPoint.dx, controlPoint.dy, end.dx, end.dy); - canvas.drawPath(path, paint); - } else if (connection.direction == 'right') { - start = connection.startSpace.position + - const Offset(150, 30); // Right center - end = connection.endSpace.position + const Offset(0, 30); // Left center + // Curved line for down connections + final controlPoint = Offset((start.dx + end.dx) / 2, start.dy + 50); + final path = Path() + ..moveTo(start.dx, start.dy) + ..quadraticBezierTo(controlPoint.dx, controlPoint.dy, end.dx, end.dy); + canvas.drawPath(path, paint); - canvas.drawLine(start, end, paint); - } else if (connection.direction == 'left') { - start = - connection.startSpace.position + const Offset(0, 30); // Left center - end = connection.endSpace.position + - const Offset(150, 30); // Right center - - canvas.drawLine(start, end, paint); - } - final dotPaint = Paint()..color = ColorsManager.blackColor; canvas.drawCircle(start, 5, dotPaint); // Start dot canvas.drawCircle(end, 5, dotPaint); // End dot diff --git a/lib/pages/spaces_management/all_spaces/widgets/plus_button_widget.dart b/lib/pages/spaces_management/all_spaces/widgets/plus_button_widget.dart index 280816a0..6c5babaf 100644 --- a/lib/pages/spaces_management/all_spaces/widgets/plus_button_widget.dart +++ b/lib/pages/spaces_management/all_spaces/widgets/plus_button_widget.dart @@ -5,7 +5,7 @@ class PlusButtonWidget extends StatelessWidget { final int index; final String direction; final Offset offset; - final Function(int index, Offset newPosition, String direction) onButtonTap; + final Function(int index, Offset newPosition) onButtonTap; const PlusButtonWidget({ super.key, @@ -19,21 +19,7 @@ class PlusButtonWidget extends StatelessWidget { Widget build(BuildContext context) { return GestureDetector( onTap: () { - Offset newPosition; - switch (direction) { - case 'left': - newPosition = const Offset(-200, 0); - break; - case 'right': - newPosition = const Offset(200, 0); - break; - case 'down': - newPosition = const Offset(0, 150); - break; - default: - newPosition = Offset.zero; - } - onButtonTap(index, newPosition, direction); + onButtonTap(index, const Offset(0, 150)); }, child: Container( width: 30, @@ -42,8 +28,11 @@ class PlusButtonWidget extends StatelessWidget { color: ColorsManager.spaceColor, shape: BoxShape.circle, ), - child: - const Icon(Icons.add, color: ColorsManager.whiteColors, size: 20), + child: const Icon( + Icons.add, + color: ColorsManager.whiteColors, + size: 20, + ), ), ); } diff --git a/lib/pages/spaces_management/all_spaces/widgets/space_card_widget.dart b/lib/pages/spaces_management/all_spaces/widgets/space_card_widget.dart index 49df9daa..7e6e132f 100644 --- a/lib/pages/spaces_management/all_spaces/widgets/space_card_widget.dart +++ b/lib/pages/spaces_management/all_spaces/widgets/space_card_widget.dart @@ -7,7 +7,7 @@ class SpaceCardWidget extends StatelessWidget { final Offset position; final bool isHovered; final Function(int index, bool isHovered) onHoverChanged; - final Function(int index, Offset newPosition, String direction) onButtonTap; + final Function(int index, Offset newPosition) onButtonTap; final Widget Function(int index) buildSpaceContainer; final ValueChanged onPositionChanged; diff --git a/lib/services/space_mana_api.dart b/lib/services/space_mana_api.dart index 19e219b6..a1372618 100644 --- a/lib/services/space_mana_api.dart +++ b/lib/services/space_mana_api.dart @@ -199,7 +199,7 @@ class CommunitySpaceManagementApi { {required String communityId, required String name, String? parentId, - String? direction, + bool isPrivate = false, required Offset position, String? spaceModelUuid, @@ -213,7 +213,7 @@ class CommunitySpaceManagementApi { 'isPrivate': isPrivate, 'x': position.dx, 'y': position.dy, - 'direction': direction, + 'icon': icon, }; if (parentId != null) { @@ -248,7 +248,7 @@ class CommunitySpaceManagementApi { required String name, String? parentId, String? icon, - String? direction, + bool isPrivate = false, required Offset position, List? tags, @@ -261,7 +261,7 @@ class CommunitySpaceManagementApi { 'isPrivate': isPrivate, 'x': position.dx, 'y': position.dy, - 'direction': direction, + 'icon': icon, 'subspace': subspaces, 'tags': tags,