From 8494f0a8f1a484148bdae6afec928c53cf738720 Mon Sep 17 00:00:00 2001 From: Faris Armoush Date: Sun, 22 Jun 2025 12:21:46 +0300 Subject: [PATCH] matched community and space models with API. --- .../views/space_management_page.dart | 30 +++-------- .../debounced_communities_service.dart | 51 +++++++------------ .../services/remote_communities_service.dart | 18 ++++--- .../models/communities_pagination_model.dart | 4 +- .../domain/models/community_model.dart | 12 +++++ .../domain/models/space_model.dart | 27 ++++------ .../space_management_communities_tree.dart | 1 - lib/utils/constants/api_const.dart | 1 + 8 files changed, 62 insertions(+), 82 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 93e2684f..957be65a 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 @@ -2,12 +2,12 @@ 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_management_v2/main_module/widgets/space_management_body.dart'; -import 'package:syncrow_web/pages/space_management_v2/modules/communities/domain/models/communities_pagination_model.dart'; -import 'package:syncrow_web/pages/space_management_v2/modules/communities/domain/models/community_model.dart'; +import 'package:syncrow_web/pages/space_management_v2/modules/communities/data/services/debounced_communities_service.dart'; +import 'package:syncrow_web/pages/space_management_v2/modules/communities/data/services/remote_communities_service.dart'; import 'package:syncrow_web/pages/space_management_v2/modules/communities/domain/params/load_communities_param.dart'; -import 'package:syncrow_web/pages/space_management_v2/modules/communities/domain/services/communities_service.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/services/api/http_service.dart'; import 'package:syncrow_web/utils/theme/responsive_text_theme.dart'; import 'package:syncrow_web/web_layout/web_scaffold.dart'; @@ -20,7 +20,9 @@ class SpaceManagementPage extends StatelessWidget { providers: [ BlocProvider( create: (context) => CommunitiesBloc( - communitiesService: _FakeCommunitiesService(), + communitiesService: DebouncedCommunitiesService( + RemoteCommunitiesService(HTTPService()), + ), )..add(const LoadCommunities(LoadCommunitiesParam())), ), BlocProvider(create: (context) => CommunitiesTreeSelectionBloc()), @@ -43,23 +45,3 @@ class SpaceManagementPage extends StatelessWidget { ); } } - -class _FakeCommunitiesService extends CommunitiesService { - @override - Future getCommunity(LoadCommunitiesParam param) { - return Future.value(const CommunitiesPaginationModel( - communities: [ - CommunityModel( - uuid: '1', - name: 'Community 1', - spaces: [], - ), - ], - page: 1, - size: 10, - hasNext: false, - totalItems: 2, - totalPages: 1, - )); - } -} diff --git a/lib/pages/space_management_v2/modules/communities/data/services/debounced_communities_service.dart b/lib/pages/space_management_v2/modules/communities/data/services/debounced_communities_service.dart index f8bd56d1..ca1923f9 100644 --- a/lib/pages/space_management_v2/modules/communities/data/services/debounced_communities_service.dart +++ b/lib/pages/space_management_v2/modules/communities/data/services/debounced_communities_service.dart @@ -4,57 +4,44 @@ import 'package:syncrow_web/pages/space_management_v2/modules/communities/domain import 'package:syncrow_web/pages/space_management_v2/modules/communities/domain/params/load_communities_param.dart'; import 'package:syncrow_web/pages/space_management_v2/modules/communities/domain/services/communities_service.dart'; -class DebouncedCommunitiesService implements CommunitiesService { - DebouncedCommunitiesService({ - required CommunitiesService communitiesService, - this.debounceDuration = const Duration(milliseconds: 400), - }) : _communitiesService = communitiesService; +final class DebouncedCommunitiesService implements CommunitiesService { + DebouncedCommunitiesService( + this._decoratee, { + this.debounceDuration = const Duration(milliseconds: 500), + }); - final CommunitiesService _communitiesService; + final CommunitiesService _decoratee; final Duration debounceDuration; Timer? _debounceTimer; - String _lastSearchQuery = ''; + Completer? _completer; @override Future getCommunity( LoadCommunitiesParam param, ) async { - if (param.search.isNotEmpty) { - return _getDebouncedCommunity(param); - } - - return _communitiesService.getCommunity(param); - } - - Future _getDebouncedCommunity( - LoadCommunitiesParam param, - ) async { - final completer = Completer(); - _debounceTimer?.cancel(); - _lastSearchQuery = param.search; + if (_completer != null && !_completer!.isCompleted) { + _completer!.completeError(Exception('Request cancelled by newer request')); + } + + _completer = Completer(); + final currentCompleter = _completer!; _debounceTimer = Timer(debounceDuration, () async { try { - if (_lastSearchQuery == param.search) { - final result = await _communitiesService.getCommunity(param); - if (!completer.isCompleted) { - completer.complete(result); - } - } else { - if (!completer.isCompleted) { - completer.complete(const CommunitiesPaginationModel.empty()); - } + final result = await _decoratee.getCommunity(param); + if (!currentCompleter.isCompleted) { + currentCompleter.complete(result); } } catch (error) { - if (!completer.isCompleted) { - completer.completeError(error); + if (!currentCompleter.isCompleted) { + currentCompleter.completeError(error); } } }); - return completer.future; + return currentCompleter.future; } } diff --git a/lib/pages/space_management_v2/modules/communities/data/services/remote_communities_service.dart b/lib/pages/space_management_v2/modules/communities/data/services/remote_communities_service.dart index e4202398..925a1cd0 100644 --- a/lib/pages/space_management_v2/modules/communities/data/services/remote_communities_service.dart +++ b/lib/pages/space_management_v2/modules/communities/data/services/remote_communities_service.dart @@ -15,10 +15,9 @@ class RemoteCommunitiesService implements CommunitiesService { static const _defaultErrorMessage = 'Failed to load communities'; @override - Future getCommunity(LoadCommunitiesParam param) async { - final projectUuid = await ProjectManager.getProjectUUID(); - if (projectUuid == null) throw APIException('Project UUID is not set'); - + Future getCommunity( + LoadCommunitiesParam param, + ) async { try { final response = await _httpService.get( path: await _makeUrl(), @@ -26,10 +25,12 @@ class RemoteCommunitiesService implements CommunitiesService { 'page': param.page, 'size': param.size, 'includeSpaces': param.includeSpaces, - if (param.search.isNotEmpty) 'search': param.search, + if (param.search.isNotEmpty && param.search != 'null') + 'search': param.search, }, expectedResponseModel: (json) { - return CommunitiesPaginationModel.fromJson(json as Map); + final data = json as Map; + return CommunitiesPaginationModel.fromJson(data); }, ); @@ -48,6 +49,9 @@ class RemoteCommunitiesService implements CommunitiesService { Future _makeUrl() async { final projectUuid = await ProjectManager.getProjectUUID(); if (projectUuid == null) throw APIException('Project UUID is required'); - return ApiEndpoints.getCommunityList.replaceAll('{projectId}', projectUuid); + return ApiEndpoints.getCommunityListv2.replaceAll( + '{projectId}', + projectUuid, + ); } } diff --git a/lib/pages/space_management_v2/modules/communities/domain/models/communities_pagination_model.dart b/lib/pages/space_management_v2/modules/communities/domain/models/communities_pagination_model.dart index f13ef8ba..a86783be 100644 --- a/lib/pages/space_management_v2/modules/communities/domain/models/communities_pagination_model.dart +++ b/lib/pages/space_management_v2/modules/communities/domain/models/communities_pagination_model.dart @@ -34,8 +34,8 @@ class CommunitiesPaginationModel extends Equatable { page: json['page'] as int? ?? 1, size: json['size'] as int? ?? 25, hasNext: json['hasNext'] as bool? ?? false, - totalItems: json['totalItems'] as int? ?? 0, - totalPages: json['totalPages'] as int? ?? 0, + totalItems: json['totalItem'] as int? ?? 0, + totalPages: json['totalPage'] as int? ?? 0, ); } diff --git a/lib/pages/space_management_v2/modules/communities/domain/models/community_model.dart b/lib/pages/space_management_v2/modules/communities/domain/models/community_model.dart index c6efad9e..ea0839f9 100644 --- a/lib/pages/space_management_v2/modules/communities/domain/models/community_model.dart +++ b/lib/pages/space_management_v2/modules/communities/domain/models/community_model.dart @@ -4,11 +4,19 @@ import 'package:syncrow_web/pages/space_management_v2/modules/communities/domain class CommunityModel extends Equatable { final String uuid; final String name; + final DateTime createdAt; + final DateTime updatedAt; + final String description; + final String externalId; final List spaces; const CommunityModel({ required this.uuid, required this.name, + required this.createdAt, + required this.updatedAt, + required this.description, + required this.externalId, required this.spaces, }); @@ -16,6 +24,10 @@ class CommunityModel extends Equatable { return CommunityModel( uuid: json['uuid'] as String, name: json['name'] as String, + createdAt: DateTime.parse(json['createdAt'] as String), + updatedAt: DateTime.parse(json['updatedAt'] as String), + description: json['description'] as String, + externalId: json['externalId'] as String, spaces: (json['spaces'] as List) .map((e) => SpaceModel.fromJson(e as Map)) .toList(), diff --git a/lib/pages/space_management_v2/modules/communities/domain/models/space_model.dart b/lib/pages/space_management_v2/modules/communities/domain/models/space_model.dart index 519e8ee7..d6007815 100644 --- a/lib/pages/space_management_v2/modules/communities/domain/models/space_model.dart +++ b/lib/pages/space_management_v2/modules/communities/domain/models/space_model.dart @@ -1,43 +1,38 @@ import 'package:equatable/equatable.dart'; -enum SpaceStatus { - active, - deleted, - parentDeleted; - - static SpaceStatus getValueFromString(String value) => switch (value) { - 'active' => active, - 'deleted' => deleted, - 'parentDeleted' => parentDeleted, - _ => active, - }; -} - class SpaceModel extends Equatable { final String uuid; + final DateTime createdAt; + final DateTime updatedAt; final String spaceName; final String icon; final List children; - final SpaceStatus status; + final SpaceModel? parent; const SpaceModel({ required this.uuid, + required this.createdAt, + required this.updatedAt, required this.spaceName, required this.icon, required this.children, - required this.status, + required this.parent, }); factory SpaceModel.fromJson(Map json) { return SpaceModel( uuid: json['uuid'] as String, + createdAt: DateTime.parse(json['createdAt'] as String), + updatedAt: DateTime.parse(json['updatedAt'] as String), spaceName: json['spaceName'] as String, icon: json['icon'] as String, children: (json['children'] as List?) ?.map((e) => SpaceModel.fromJson(e as Map)) .toList() ?? [], - status: SpaceStatus.getValueFromString(json['status'] as String), + parent: json['parent'] != null + ? SpaceModel.fromJson(json['parent'] as Map) + : null, ); } diff --git a/lib/pages/space_management_v2/modules/communities/presentation/widgets/space_management_communities_tree.dart b/lib/pages/space_management_v2/modules/communities/presentation/widgets/space_management_communities_tree.dart index 51322b52..b9902bd6 100644 --- a/lib/pages/space_management_v2/modules/communities/presentation/widgets/space_management_communities_tree.dart +++ b/lib/pages/space_management_v2/modules/communities/presentation/widgets/space_management_communities_tree.dart @@ -146,7 +146,6 @@ class _SpaceManagementCommunitiesTreeState Widget _buildCommunityTile(BuildContext context, CommunityModel community) { final spaces = community.spaces - .where((space) => space.status == SpaceStatus.active) .map((space) => _buildSpaceTile( space: space, community: community, diff --git a/lib/utils/constants/api_const.dart b/lib/utils/constants/api_const.dart index d58d0f28..048f3000 100644 --- a/lib/utils/constants/api_const.dart +++ b/lib/utils/constants/api_const.dart @@ -46,6 +46,7 @@ abstract class ApiEndpoints { // Community Module static const String createCommunity = '/projects/{projectId}/communities'; static const String getCommunityList = '/projects/{projectId}/communities'; + static const String getCommunityListv2 = '/projects/{projectId}/communities/v2'; static const String getCommunityById = '/projects/{projectId}/communities/{communityId}'; static const String updateCommunity =