mirror of
https://github.com/SyncrowIOT/web.git
synced 2025-07-10 15:17:31 +00:00
Added pagination and search logic in space tree
This commit is contained in:
@ -34,9 +34,8 @@ class CommunityDropdown extends StatelessWidget {
|
|||||||
const SizedBox(height: 8),
|
const SizedBox(height: 8),
|
||||||
BlocBuilder<SpaceTreeBloc, SpaceTreeState>(
|
BlocBuilder<SpaceTreeBloc, SpaceTreeState>(
|
||||||
builder: (context, state) {
|
builder: (context, state) {
|
||||||
List<CommunityModel> communities = state.isSearching
|
List<CommunityModel> communities =
|
||||||
? state.filteredCommunity
|
state.searchQuery.isNotEmpty ? state.filteredCommunity : state.communityList;
|
||||||
: state.communityList;
|
|
||||||
|
|
||||||
return SizedBox(
|
return SizedBox(
|
||||||
child: DropdownButtonFormField<String>(
|
child: DropdownButtonFormField<String>(
|
||||||
|
@ -1,7 +1,10 @@
|
|||||||
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:syncrow_web/pages/common/bloc/project_manager.dart';
|
import 'package:syncrow_web/pages/common/bloc/project_manager.dart';
|
||||||
import 'package:syncrow_web/pages/space_tree/bloc/space_tree_event.dart';
|
import 'package:syncrow_web/pages/space_tree/bloc/space_tree_event.dart';
|
||||||
import 'package:syncrow_web/pages/space_tree/bloc/space_tree_state.dart';
|
import 'package:syncrow_web/pages/space_tree/bloc/space_tree_state.dart';
|
||||||
|
import 'package:syncrow_web/pages/space_tree/model/pagination_model.dart';
|
||||||
import 'package:syncrow_web/pages/spaces_management/all_spaces/model/community_model.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 'package:syncrow_web/pages/spaces_management/all_spaces/model/space_model.dart';
|
||||||
import 'package:syncrow_web/services/space_mana_api.dart';
|
import 'package:syncrow_web/services/space_mana_api.dart';
|
||||||
@ -18,7 +21,10 @@ class SpaceTreeBloc extends Bloc<SpaceTreeEvent, SpaceTreeState> {
|
|||||||
on<ClearCachedData>(_clearCachedData);
|
on<ClearCachedData>(_clearCachedData);
|
||||||
on<OnCommunityAdded>(_onCommunityAdded);
|
on<OnCommunityAdded>(_onCommunityAdded);
|
||||||
on<OnCommunityUpdated>(_onCommunityUpdate);
|
on<OnCommunityUpdated>(_onCommunityUpdate);
|
||||||
|
on<PaginationEvent>(_fetchPaginationSpaces);
|
||||||
|
on<DebouncedSearchEvent>(_onDebouncedSearch);
|
||||||
}
|
}
|
||||||
|
Timer _timer = Timer(const Duration(microseconds: 0), () {});
|
||||||
|
|
||||||
void _onCommunityUpdate(
|
void _onCommunityUpdate(
|
||||||
OnCommunityUpdated event,
|
OnCommunityUpdated event,
|
||||||
@ -37,7 +43,7 @@ class SpaceTreeBloc extends Bloc<SpaceTreeEvent, SpaceTreeState> {
|
|||||||
updatedCommunities[index] = updatedCommunity;
|
updatedCommunities[index] = updatedCommunity;
|
||||||
emit(state.copyWith(communitiesList: updatedCommunities));
|
emit(state.copyWith(communitiesList: updatedCommunities));
|
||||||
} else {
|
} else {
|
||||||
emit(SpaceTreeErrorState('Community not found in the list.'));
|
emit(const SpaceTreeErrorState('Community not found in the list.'));
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
emit(SpaceTreeErrorState('Error updating community: $e'));
|
emit(SpaceTreeErrorState('Error updating community: $e'));
|
||||||
@ -49,8 +55,8 @@ class SpaceTreeBloc extends Bloc<SpaceTreeEvent, SpaceTreeState> {
|
|||||||
try {
|
try {
|
||||||
final projectUuid = await ProjectManager.getProjectUUID() ?? '';
|
final projectUuid = await ProjectManager.getProjectUUID() ?? '';
|
||||||
|
|
||||||
List<CommunityModel> communities =
|
PaginationModel paginationModel = await CommunitySpaceManagementApi()
|
||||||
await CommunitySpaceManagementApi().fetchCommunities(projectUuid, includeSpaces: true);
|
.fetchCommunitiesAndSpaces(projectId: projectUuid, page: 1);
|
||||||
|
|
||||||
// List<CommunityModel> updatedCommunities = await Future.wait(
|
// List<CommunityModel> updatedCommunities = await Future.wait(
|
||||||
// communities.map((community) async {
|
// communities.map((community) async {
|
||||||
@ -69,12 +75,38 @@ class SpaceTreeBloc extends Bloc<SpaceTreeEvent, SpaceTreeState> {
|
|||||||
// }).toList(),
|
// }).toList(),
|
||||||
// );
|
// );
|
||||||
|
|
||||||
emit(state.copyWith(communitiesList: communities, expandedCommunity: [], expandedSpaces: []));
|
emit(state.copyWith(
|
||||||
|
communitiesList: paginationModel.communities,
|
||||||
|
expandedCommunity: [],
|
||||||
|
expandedSpaces: [],
|
||||||
|
paginationModel: paginationModel));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
emit(SpaceTreeErrorState('Error loading communities and spaces: $e'));
|
emit(SpaceTreeErrorState('Error loading communities and spaces: $e'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_fetchPaginationSpaces(PaginationEvent event, Emitter<SpaceTreeState> emit) async {
|
||||||
|
emit(state.copyWith(paginationIsLoading: true));
|
||||||
|
PaginationModel paginationModel = event.paginationModel;
|
||||||
|
List<CommunityModel> communities = List<CommunityModel>.from(event.communities);
|
||||||
|
try {
|
||||||
|
if (paginationModel.hasNext && state.searchQuery.isEmpty) {
|
||||||
|
final projectUuid = await ProjectManager.getProjectUUID() ?? '';
|
||||||
|
|
||||||
|
paginationModel = await CommunitySpaceManagementApi().fetchCommunitiesAndSpaces(
|
||||||
|
projectId: projectUuid, page: paginationModel.pageNum, search: state.searchQuery);
|
||||||
|
|
||||||
|
communities.addAll(paginationModel.communities);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
emit(SpaceTreeErrorState('Error loading communities and spaces: $e'));
|
||||||
|
}
|
||||||
|
emit(state.copyWith(
|
||||||
|
communitiesList: communities,
|
||||||
|
paginationModel: paginationModel,
|
||||||
|
paginationIsLoading: false));
|
||||||
|
}
|
||||||
|
|
||||||
void _onCommunityAdded(OnCommunityAdded event, Emitter<SpaceTreeState> emit) async {
|
void _onCommunityAdded(OnCommunityAdded event, Emitter<SpaceTreeState> emit) async {
|
||||||
final updatedCommunities = List<CommunityModel>.from(state.communityList);
|
final updatedCommunities = List<CommunityModel>.from(state.communityList);
|
||||||
updatedCommunities.add(event.newCommunity);
|
updatedCommunities.add(event.newCommunity);
|
||||||
@ -264,28 +296,52 @@ class SpaceTreeBloc extends Bloc<SpaceTreeEvent, SpaceTreeState> {
|
|||||||
|
|
||||||
_onSearch(SearchQueryEvent event, Emitter<SpaceTreeState> emit) async {
|
_onSearch(SearchQueryEvent event, Emitter<SpaceTreeState> emit) async {
|
||||||
try {
|
try {
|
||||||
List<CommunityModel> communities = List.from(state.communityList);
|
const duration = Duration(seconds: 1);
|
||||||
List<CommunityModel> filteredCommunity = [];
|
if (_timer.isActive) {
|
||||||
|
_timer.cancel(); // clear timer
|
||||||
|
}
|
||||||
|
_timer = Timer(duration, () async => add(DebouncedSearchEvent(event.searchQuery)));
|
||||||
|
|
||||||
|
// List<CommunityModel> communities = List.from(state.communityList);
|
||||||
|
// List<CommunityModel> filteredCommunity = [];
|
||||||
|
|
||||||
// Filter communities and expand only those that match the query
|
// Filter communities and expand only those that match the query
|
||||||
filteredCommunity = communities.where((community) {
|
// filteredCommunity = communities.where((community) {
|
||||||
final containsQueryInCommunity =
|
// final containsQueryInCommunity =
|
||||||
community.name.toLowerCase().contains(event.searchQuery.toLowerCase());
|
// community.name.toLowerCase().contains(event.searchQuery.toLowerCase());
|
||||||
final containsQueryInSpaces =
|
// final containsQueryInSpaces =
|
||||||
community.spaces.any((space) => _containsQuery(space, event.searchQuery.toLowerCase()));
|
// community.spaces.any((space) => _containsQuery(space, event.searchQuery.toLowerCase()));
|
||||||
|
|
||||||
return containsQueryInCommunity || containsQueryInSpaces;
|
// return containsQueryInCommunity || containsQueryInSpaces;
|
||||||
}).toList();
|
// }).toList();
|
||||||
|
|
||||||
emit(state.copyWith(
|
// emit(state.copyWith(
|
||||||
filteredCommunity: filteredCommunity,
|
// filteredCommunity: filteredCommunity,
|
||||||
isSearching: event.searchQuery.isNotEmpty,
|
// isSearching: event.searchQuery.isNotEmpty,
|
||||||
searchQuery: event.searchQuery));
|
// searchQuery: event.searchQuery));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
emit(const SpaceTreeErrorState('Something went wrong'));
|
emit(const SpaceTreeErrorState('Something went wrong'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_onDebouncedSearch(DebouncedSearchEvent event, Emitter<SpaceTreeState> emit) async {
|
||||||
|
emit(state.copyWith(
|
||||||
|
isSearching: true,
|
||||||
|
));
|
||||||
|
PaginationModel paginationModel = const PaginationModel.emptyConstructor();
|
||||||
|
try {
|
||||||
|
final projectUuid = await ProjectManager.getProjectUUID() ?? '';
|
||||||
|
|
||||||
|
paginationModel = await CommunitySpaceManagementApi()
|
||||||
|
.fetchCommunitiesAndSpaces(projectId: projectUuid, page: 1, search: event.searchQuery);
|
||||||
|
} catch (_) {}
|
||||||
|
|
||||||
|
emit(state.copyWith(
|
||||||
|
filteredCommunity: paginationModel.communities,
|
||||||
|
isSearching: false,
|
||||||
|
searchQuery: event.searchQuery));
|
||||||
|
}
|
||||||
|
|
||||||
_clearAllData(ClearAllData event, Emitter<SpaceTreeState> emit) async {
|
_clearAllData(ClearAllData event, Emitter<SpaceTreeState> emit) async {
|
||||||
try {
|
try {
|
||||||
emit(state.copyWith(
|
emit(state.copyWith(
|
||||||
@ -323,13 +379,13 @@ class SpaceTreeBloc extends Bloc<SpaceTreeEvent, SpaceTreeState> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Helper function to determine if any space or its children match the search query
|
// Helper function to determine if any space or its children match the search query
|
||||||
bool _containsQuery(SpaceModel space, String query) {
|
// bool _containsQuery(SpaceModel space, String query) {
|
||||||
final matchesSpace = space.name.toLowerCase().contains(query);
|
// final matchesSpace = space.name.toLowerCase().contains(query);
|
||||||
final matchesChildren =
|
// final matchesChildren =
|
||||||
space.children.any((child) => _containsQuery(child, query)); // Recursive check for children
|
// space.children.any((child) => _containsQuery(child, query)); // Recursive check for children
|
||||||
|
|
||||||
return matchesSpace || matchesChildren;
|
// return matchesSpace || matchesChildren;
|
||||||
}
|
// }
|
||||||
|
|
||||||
List<String> _getAllChildIds(List<SpaceModel> spaces) {
|
List<String> _getAllChildIds(List<SpaceModel> spaces) {
|
||||||
List<String> ids = [];
|
List<String> ids = [];
|
||||||
@ -403,6 +459,7 @@ class SpaceTreeBloc extends Bloc<SpaceTreeEvent, SpaceTreeState> {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> close() async {
|
Future<void> close() async {
|
||||||
|
_timer.cancel();
|
||||||
super.close();
|
super.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import 'package:equatable/equatable.dart';
|
import 'package:equatable/equatable.dart';
|
||||||
|
import 'package:syncrow_web/pages/space_tree/model/pagination_model.dart';
|
||||||
import 'package:syncrow_web/pages/spaces_management/all_spaces/model/community_model.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 'package:syncrow_web/pages/spaces_management/all_spaces/model/space_model.dart';
|
||||||
|
|
||||||
@ -11,6 +12,16 @@ class SpaceTreeEvent extends Equatable {
|
|||||||
|
|
||||||
class InitialEvent extends SpaceTreeEvent {}
|
class InitialEvent extends SpaceTreeEvent {}
|
||||||
|
|
||||||
|
class PaginationEvent extends SpaceTreeEvent {
|
||||||
|
final PaginationModel paginationModel;
|
||||||
|
final List<CommunityModel> communities;
|
||||||
|
|
||||||
|
const PaginationEvent(this.paginationModel, this.communities);
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<Object> get props => [paginationModel, communities];
|
||||||
|
}
|
||||||
|
|
||||||
class SearchForSpace extends SpaceTreeEvent {
|
class SearchForSpace extends SpaceTreeEvent {
|
||||||
final String searchQuery;
|
final String searchQuery;
|
||||||
|
|
||||||
@ -69,6 +80,15 @@ class SearchQueryEvent extends SpaceTreeEvent {
|
|||||||
List<Object> get props => [searchQuery];
|
List<Object> get props => [searchQuery];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class DebouncedSearchEvent extends SpaceTreeEvent {
|
||||||
|
final String searchQuery;
|
||||||
|
|
||||||
|
const DebouncedSearchEvent(this.searchQuery);
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<Object> get props => [searchQuery];
|
||||||
|
}
|
||||||
|
|
||||||
class OnCommunityAdded extends SpaceTreeEvent {
|
class OnCommunityAdded extends SpaceTreeEvent {
|
||||||
final CommunityModel newCommunity;
|
final CommunityModel newCommunity;
|
||||||
const OnCommunityAdded(this.newCommunity);
|
const OnCommunityAdded(this.newCommunity);
|
||||||
@ -85,7 +105,6 @@ class OnCommunityUpdated extends SpaceTreeEvent {
|
|||||||
List<Object> get props => [updatedCommunity];
|
List<Object> get props => [updatedCommunity];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class ClearAllData extends SpaceTreeEvent {}
|
class ClearAllData extends SpaceTreeEvent {}
|
||||||
|
|
||||||
class ClearCachedData extends SpaceTreeEvent {}
|
class ClearCachedData extends SpaceTreeEvent {}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import 'package:equatable/equatable.dart';
|
import 'package:equatable/equatable.dart';
|
||||||
|
import 'package:syncrow_web/pages/space_tree/model/pagination_model.dart';
|
||||||
import 'package:syncrow_web/pages/spaces_management/all_spaces/model/community_model.dart';
|
import 'package:syncrow_web/pages/spaces_management/all_spaces/model/community_model.dart';
|
||||||
|
|
||||||
class SpaceTreeState extends Equatable {
|
class SpaceTreeState extends Equatable {
|
||||||
@ -12,6 +13,8 @@ class SpaceTreeState extends Equatable {
|
|||||||
final List<String> soldCheck;
|
final List<String> soldCheck;
|
||||||
final bool isSearching;
|
final bool isSearching;
|
||||||
final String searchQuery;
|
final String searchQuery;
|
||||||
|
final PaginationModel paginationModel;
|
||||||
|
final bool paginationIsLoading;
|
||||||
|
|
||||||
const SpaceTreeState(
|
const SpaceTreeState(
|
||||||
{this.communityList = const [],
|
{this.communityList = const [],
|
||||||
@ -23,7 +26,9 @@ class SpaceTreeState extends Equatable {
|
|||||||
this.soldCheck = const [],
|
this.soldCheck = const [],
|
||||||
this.isSearching = false,
|
this.isSearching = false,
|
||||||
this.selectedCommunityAndSpaces = const {},
|
this.selectedCommunityAndSpaces = const {},
|
||||||
this.searchQuery = ''});
|
this.searchQuery = '',
|
||||||
|
this.paginationModel = const PaginationModel.emptyConstructor(),
|
||||||
|
this.paginationIsLoading = false});
|
||||||
|
|
||||||
SpaceTreeState copyWith(
|
SpaceTreeState copyWith(
|
||||||
{List<CommunityModel>? communitiesList,
|
{List<CommunityModel>? communitiesList,
|
||||||
@ -35,7 +40,9 @@ class SpaceTreeState extends Equatable {
|
|||||||
List<String>? soldCheck,
|
List<String>? soldCheck,
|
||||||
bool? isSearching,
|
bool? isSearching,
|
||||||
Map<String, List<String>>? selectedCommunityAndSpaces,
|
Map<String, List<String>>? selectedCommunityAndSpaces,
|
||||||
String? searchQuery}) {
|
String? searchQuery,
|
||||||
|
PaginationModel? paginationModel,
|
||||||
|
bool? paginationIsLoading}) {
|
||||||
return SpaceTreeState(
|
return SpaceTreeState(
|
||||||
communityList: communitiesList ?? this.communityList,
|
communityList: communitiesList ?? this.communityList,
|
||||||
filteredCommunity: filteredCommunity ?? this.filteredCommunity,
|
filteredCommunity: filteredCommunity ?? this.filteredCommunity,
|
||||||
@ -46,7 +53,9 @@ class SpaceTreeState extends Equatable {
|
|||||||
soldCheck: soldCheck ?? this.soldCheck,
|
soldCheck: soldCheck ?? this.soldCheck,
|
||||||
isSearching: isSearching ?? this.isSearching,
|
isSearching: isSearching ?? this.isSearching,
|
||||||
selectedCommunityAndSpaces: selectedCommunityAndSpaces ?? this.selectedCommunityAndSpaces,
|
selectedCommunityAndSpaces: selectedCommunityAndSpaces ?? this.selectedCommunityAndSpaces,
|
||||||
searchQuery: searchQuery ?? this.searchQuery);
|
searchQuery: searchQuery ?? this.searchQuery,
|
||||||
|
paginationModel: paginationModel ?? this.paginationModel,
|
||||||
|
paginationIsLoading: paginationIsLoading ?? this.paginationIsLoading);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -60,7 +69,9 @@ class SpaceTreeState extends Equatable {
|
|||||||
soldCheck,
|
soldCheck,
|
||||||
isSearching,
|
isSearching,
|
||||||
selectedCommunityAndSpaces,
|
selectedCommunityAndSpaces,
|
||||||
searchQuery
|
searchQuery,
|
||||||
|
paginationModel,
|
||||||
|
paginationIsLoading
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
20
lib/pages/space_tree/model/pagination_model.dart
Normal file
20
lib/pages/space_tree/model/pagination_model.dart
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
import 'package:syncrow_web/pages/spaces_management/all_spaces/model/community_model.dart';
|
||||||
|
|
||||||
|
class PaginationModel {
|
||||||
|
final int pageNum;
|
||||||
|
final bool hasNext;
|
||||||
|
final int size;
|
||||||
|
final List<CommunityModel> communities;
|
||||||
|
|
||||||
|
const PaginationModel(
|
||||||
|
{required this.pageNum,
|
||||||
|
required this.hasNext,
|
||||||
|
required this.size,
|
||||||
|
required this.communities});
|
||||||
|
|
||||||
|
const PaginationModel.emptyConstructor()
|
||||||
|
: pageNum = 1,
|
||||||
|
hasNext = true,
|
||||||
|
size = 10,
|
||||||
|
communities = const [];
|
||||||
|
}
|
@ -34,7 +34,8 @@ class _SpaceTreeViewState extends State<SpaceTreeView> {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return BlocBuilder<SpaceTreeBloc, SpaceTreeState>(builder: (context, state) {
|
return BlocBuilder<SpaceTreeBloc, SpaceTreeState>(builder: (context, state) {
|
||||||
List<CommunityModel> list = state.isSearching ? state.filteredCommunity : state.communityList;
|
List<CommunityModel> list =
|
||||||
|
state.searchQuery.isNotEmpty ? state.filteredCommunity : state.communityList;
|
||||||
return Container(
|
return Container(
|
||||||
height: MediaQuery.sizeOf(context).height,
|
height: MediaQuery.sizeOf(context).height,
|
||||||
decoration: widget.isSide == true
|
decoration: widget.isSide == true
|
||||||
@ -61,7 +62,8 @@ class _SpaceTreeViewState extends State<SpaceTreeView> {
|
|||||||
borderRadius: const BorderRadius.all(Radius.circular(20)),
|
borderRadius: const BorderRadius.all(Radius.circular(20)),
|
||||||
border: Border.all(color: ColorsManager.grayBorder)),
|
border: Border.all(color: ColorsManager.grayBorder)),
|
||||||
child: TextFormField(
|
child: TextFormField(
|
||||||
style: const TextStyle(color: Colors.black),
|
style: context.textTheme.bodyMedium
|
||||||
|
?.copyWith(color: ColorsManager.blackColor),
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
context.read<SpaceTreeBloc>().add(SearchQueryEvent(value));
|
context.read<SpaceTreeBloc>().add(SearchQueryEvent(value));
|
||||||
},
|
},
|
||||||
@ -94,7 +96,9 @@ class _SpaceTreeViewState extends State<SpaceTreeView> {
|
|||||||
),
|
),
|
||||||
const SizedBox(height: 16),
|
const SizedBox(height: 16),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: ListView(
|
child: state.isSearching
|
||||||
|
? const Center(child: CircularProgressIndicator())
|
||||||
|
: ListView(
|
||||||
shrinkWrap: true,
|
shrinkWrap: true,
|
||||||
scrollDirection: Axis.horizontal,
|
scrollDirection: Axis.horizontal,
|
||||||
children: [
|
children: [
|
||||||
@ -115,59 +119,70 @@ class _SpaceTreeViewState extends State<SpaceTreeView> {
|
|||||||
scrollbarOrientation: ScrollbarOrientation.left,
|
scrollbarOrientation: ScrollbarOrientation.left,
|
||||||
thumbVisibility: true,
|
thumbVisibility: true,
|
||||||
controller: _scrollController,
|
controller: _scrollController,
|
||||||
|
child: NotificationListener(
|
||||||
|
onNotification: (notification) {
|
||||||
|
if (notification is ScrollEndNotification &&
|
||||||
|
notification.metrics.extentAfter == 0) {
|
||||||
|
// If the user has reached the end of the list Load more data
|
||||||
|
context.read<SpaceTreeBloc>().add(PaginationEvent(
|
||||||
|
state.paginationModel, state.communityList));
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
},
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.only(left: 16),
|
padding: const EdgeInsets.only(left: 16),
|
||||||
child: ListView(
|
child: ListView.builder(
|
||||||
controller: _scrollController,
|
|
||||||
shrinkWrap: true,
|
shrinkWrap: true,
|
||||||
children: list
|
itemCount: list.length,
|
||||||
.map(
|
controller: _scrollController,
|
||||||
(community) => CustomExpansionTileSpaceTree(
|
itemBuilder: (context, index) {
|
||||||
title: community.name,
|
return CustomExpansionTileSpaceTree(
|
||||||
|
title: list[index].name,
|
||||||
isSelected: state.selectedCommunities
|
isSelected: state.selectedCommunities
|
||||||
.contains(community.uuid),
|
.contains(list[index].uuid),
|
||||||
isSoldCheck: state.selectedCommunities
|
isSoldCheck: state.selectedCommunities
|
||||||
.contains(community.uuid),
|
.contains(list[index].uuid),
|
||||||
onExpansionChanged: () {
|
onExpansionChanged: () {
|
||||||
context
|
context.read<SpaceTreeBloc>().add(
|
||||||
.read<SpaceTreeBloc>()
|
OnCommunityExpanded(list[index].uuid));
|
||||||
.add(OnCommunityExpanded(community.uuid));
|
|
||||||
},
|
},
|
||||||
isExpanded: state.expandedCommunities
|
isExpanded: state.expandedCommunities
|
||||||
.contains(community.uuid),
|
.contains(list[index].uuid),
|
||||||
onItemSelected: () {
|
onItemSelected: () {
|
||||||
context.read<SpaceTreeBloc>().add(
|
context.read<SpaceTreeBloc>().add(
|
||||||
OnCommunitySelected(
|
OnCommunitySelected(list[index].uuid,
|
||||||
community.uuid, community.spaces));
|
list[index].spaces));
|
||||||
widget.onSelect();
|
widget.onSelect();
|
||||||
},
|
},
|
||||||
children: community.spaces.map((space) {
|
children: list[index].spaces.map((space) {
|
||||||
return CustomExpansionTileSpaceTree(
|
return CustomExpansionTileSpaceTree(
|
||||||
title: space.name,
|
title: space.name,
|
||||||
isExpanded:
|
isExpanded: state.expandedSpaces
|
||||||
state.expandedSpaces.contains(space.uuid),
|
.contains(space.uuid),
|
||||||
onItemSelected: () {
|
onItemSelected: () {
|
||||||
context.read<SpaceTreeBloc>().add(
|
context.read<SpaceTreeBloc>().add(
|
||||||
OnSpaceSelected(community, space.uuid ?? '',
|
OnSpaceSelected(
|
||||||
|
list[index],
|
||||||
|
space.uuid ?? '',
|
||||||
space.children));
|
space.children));
|
||||||
widget.onSelect();
|
widget.onSelect();
|
||||||
},
|
},
|
||||||
onExpansionChanged: () {
|
onExpansionChanged: () {
|
||||||
context.read<SpaceTreeBloc>().add(
|
context.read<SpaceTreeBloc>().add(
|
||||||
OnSpaceExpanded(
|
OnSpaceExpanded(list[index].uuid,
|
||||||
community.uuid, space.uuid ?? ''));
|
space.uuid ?? ''));
|
||||||
},
|
},
|
||||||
isSelected:
|
isSelected: state.selectedSpaces
|
||||||
state.selectedSpaces.contains(space.uuid) ||
|
.contains(space.uuid) ||
|
||||||
|
state.soldCheck.contains(space.uuid),
|
||||||
|
isSoldCheck:
|
||||||
state.soldCheck.contains(space.uuid),
|
state.soldCheck.contains(space.uuid),
|
||||||
isSoldCheck: state.soldCheck.contains(space.uuid),
|
|
||||||
children: _buildNestedSpaces(
|
children: _buildNestedSpaces(
|
||||||
context, state, space, community),
|
context, state, space, list[index]),
|
||||||
);
|
);
|
||||||
}).toList(),
|
}).toList(),
|
||||||
),
|
);
|
||||||
)
|
}),
|
||||||
.toList(),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -175,7 +190,7 @@ class _SpaceTreeViewState extends State<SpaceTreeView> {
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
if (state.paginationIsLoading) const CircularProgressIndicator(),
|
||||||
// Expanded(
|
// Expanded(
|
||||||
// child: Padding(
|
// child: Padding(
|
||||||
// padding: const EdgeInsets.all(8.0),
|
// padding: const EdgeInsets.all(8.0),
|
||||||
|
@ -22,11 +22,11 @@ class CommunityModel {
|
|||||||
|
|
||||||
factory CommunityModel.fromJson(Map<String, dynamic> json) {
|
factory CommunityModel.fromJson(Map<String, dynamic> json) {
|
||||||
return CommunityModel(
|
return CommunityModel(
|
||||||
uuid: json['uuid'],
|
uuid: json['uuid'] ?? '',
|
||||||
createdAt: DateTime.parse(json['createdAt']),
|
createdAt: DateTime.parse(json['createdAt'] ?? ''),
|
||||||
updatedAt: DateTime.parse(json['updatedAt']),
|
updatedAt: DateTime.parse(json['updatedAt'] ?? ''),
|
||||||
name: json['name'],
|
name: json['name'] ?? '',
|
||||||
description: json['description'],
|
description: json['description'] ?? '',
|
||||||
region: json['region'] != null ? RegionModel.fromJson(json['region']) : null,
|
region: json['region'] != null ? RegionModel.fromJson(json['region']) : null,
|
||||||
spaces: json['spaces'] != null
|
spaces: json['spaces'] != null
|
||||||
? (json['spaces'] as List).map((space) => SpaceModel.fromJson(space)).toList()
|
? (json['spaces'] as List).map((space) => SpaceModel.fromJson(space)).toList()
|
||||||
|
@ -23,9 +23,7 @@ class DevicesManagementApi {
|
|||||||
: ApiEndpoints.getAllDevices.replaceAll('{projectId}', projectId),
|
: ApiEndpoints.getAllDevices.replaceAll('{projectId}', projectId),
|
||||||
showServerMessage: true,
|
showServerMessage: true,
|
||||||
expectedResponseModel: (json) {
|
expectedResponseModel: (json) {
|
||||||
List<dynamic> jsonData = communityId.isNotEmpty && spaceId.isNotEmpty
|
List<dynamic> jsonData = json['data'];
|
||||||
? json['data']
|
|
||||||
: json;
|
|
||||||
List<AllDevicesModel> devicesList = jsonData.map((jsonItem) {
|
List<AllDevicesModel> devicesList = jsonData.map((jsonItem) {
|
||||||
return AllDevicesModel.fromJson(jsonItem);
|
return AllDevicesModel.fromJson(jsonItem);
|
||||||
}).toList();
|
}).toList();
|
||||||
@ -93,8 +91,7 @@ class DevicesManagementApi {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<bool> deviceBatchControl(
|
Future<bool> deviceBatchControl(List<String> uuids, String code, dynamic value) async {
|
||||||
List<String> uuids, String code, dynamic value) async {
|
|
||||||
try {
|
try {
|
||||||
final body = {
|
final body = {
|
||||||
'devicesUuid': uuids,
|
'devicesUuid': uuids,
|
||||||
@ -118,8 +115,7 @@ class DevicesManagementApi {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static Future<List<DeviceModel>> getDevicesByGatewayId(
|
static Future<List<DeviceModel>> getDevicesByGatewayId(String gatewayId) async {
|
||||||
String gatewayId) async {
|
|
||||||
final response = await HTTPService().get(
|
final response = await HTTPService().get(
|
||||||
path: ApiEndpoints.gatewayApi.replaceAll('{gatewayUuid}', gatewayId),
|
path: ApiEndpoints.gatewayApi.replaceAll('{gatewayUuid}', gatewayId),
|
||||||
showServerMessage: false,
|
showServerMessage: false,
|
||||||
@ -153,9 +149,7 @@ class DevicesManagementApi {
|
|||||||
String code,
|
String code,
|
||||||
) async {
|
) async {
|
||||||
final response = await HTTPService().get(
|
final response = await HTTPService().get(
|
||||||
path: ApiEndpoints.getDeviceLogs
|
path: ApiEndpoints.getDeviceLogs.replaceAll('{uuid}', uuid).replaceAll('{code}', code),
|
||||||
.replaceAll('{uuid}', uuid)
|
|
||||||
.replaceAll('{code}', code),
|
|
||||||
showServerMessage: false,
|
showServerMessage: false,
|
||||||
expectedResponseModel: (json) {
|
expectedResponseModel: (json) {
|
||||||
return DeviceReport.fromJson(json);
|
return DeviceReport.fromJson(json);
|
||||||
@ -228,8 +222,7 @@ class DevicesManagementApi {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<bool> addScheduleRecord(
|
Future<bool> addScheduleRecord(ScheduleEntry sendSchedule, String uuid) async {
|
||||||
ScheduleEntry sendSchedule, String uuid) async {
|
|
||||||
try {
|
try {
|
||||||
final response = await HTTPService().post(
|
final response = await HTTPService().post(
|
||||||
path: ApiEndpoints.scheduleByDeviceId.replaceAll('{deviceUuid}', uuid),
|
path: ApiEndpoints.scheduleByDeviceId.replaceAll('{deviceUuid}', uuid),
|
||||||
@ -246,8 +239,7 @@ class DevicesManagementApi {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<List<ScheduleModel>> getDeviceSchedules(
|
Future<List<ScheduleModel>> getDeviceSchedules(String uuid, String category) async {
|
||||||
String uuid, String category) async {
|
|
||||||
try {
|
try {
|
||||||
final response = await HTTPService().get(
|
final response = await HTTPService().get(
|
||||||
path: ApiEndpoints.getScheduleByDeviceId
|
path: ApiEndpoints.getScheduleByDeviceId
|
||||||
@ -270,9 +262,7 @@ class DevicesManagementApi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<bool> updateScheduleRecord(
|
Future<bool> updateScheduleRecord(
|
||||||
{required bool enable,
|
{required bool enable, required String uuid, required String scheduleId}) async {
|
||||||
required String uuid,
|
|
||||||
required String scheduleId}) async {
|
|
||||||
try {
|
try {
|
||||||
final response = await HTTPService().put(
|
final response = await HTTPService().put(
|
||||||
path: ApiEndpoints.updateScheduleByDeviceId
|
path: ApiEndpoints.updateScheduleByDeviceId
|
||||||
@ -293,8 +283,7 @@ class DevicesManagementApi {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<bool> editScheduleRecord(
|
Future<bool> editScheduleRecord(String uuid, ScheduleEntry newSchedule) async {
|
||||||
String uuid, ScheduleEntry newSchedule) async {
|
|
||||||
try {
|
try {
|
||||||
final response = await HTTPService().put(
|
final response = await HTTPService().put(
|
||||||
path: ApiEndpoints.scheduleByDeviceId.replaceAll('{deviceUuid}', uuid),
|
path: ApiEndpoints.scheduleByDeviceId.replaceAll('{deviceUuid}', uuid),
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:syncrow_web/pages/space_tree/model/pagination_model.dart';
|
||||||
import 'package:syncrow_web/pages/spaces_management/all_spaces/model/community_model.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/create_subspace_model.dart';
|
||||||
import 'package:syncrow_web/pages/spaces_management/all_spaces/model/space_model.dart';
|
import 'package:syncrow_web/pages/spaces_management/all_spaces/model/space_model.dart';
|
||||||
@ -11,8 +12,7 @@ import 'package:syncrow_web/utils/constants/api_const.dart';
|
|||||||
|
|
||||||
class CommunitySpaceManagementApi {
|
class CommunitySpaceManagementApi {
|
||||||
// Community Management APIs
|
// Community Management APIs
|
||||||
Future<List<CommunityModel>> fetchCommunities(String projectId,
|
Future<List<CommunityModel>> fetchCommunities(String projectId, {int page = 1}) async {
|
||||||
{int page = 1, bool includeSpaces = false}) async {
|
|
||||||
try {
|
try {
|
||||||
List<CommunityModel> allCommunities = [];
|
List<CommunityModel> allCommunities = [];
|
||||||
bool hasNext = true;
|
bool hasNext = true;
|
||||||
@ -20,7 +20,9 @@ class CommunitySpaceManagementApi {
|
|||||||
while (hasNext) {
|
while (hasNext) {
|
||||||
await HTTPService().get(
|
await HTTPService().get(
|
||||||
path: ApiEndpoints.getCommunityList.replaceAll('{projectId}', projectId),
|
path: ApiEndpoints.getCommunityList.replaceAll('{projectId}', projectId),
|
||||||
queryParameters: {'page': page, 'includeSpaces': includeSpaces},
|
queryParameters: {
|
||||||
|
'page': page,
|
||||||
|
},
|
||||||
expectedResponseModel: (json) {
|
expectedResponseModel: (json) {
|
||||||
try {
|
try {
|
||||||
List<dynamic> jsonData = json['data'] ?? [];
|
List<dynamic> jsonData = json['data'] ?? [];
|
||||||
@ -46,6 +48,38 @@ class CommunitySpaceManagementApi {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<PaginationModel> fetchCommunitiesAndSpaces(
|
||||||
|
{required String projectId, int page = 1, String search = ''}) async {
|
||||||
|
PaginationModel paginationModel = const PaginationModel.emptyConstructor();
|
||||||
|
|
||||||
|
try {
|
||||||
|
bool hasNext = false;
|
||||||
|
await HTTPService().get(
|
||||||
|
path: ApiEndpoints.getCommunityList.replaceAll('{projectId}', projectId),
|
||||||
|
queryParameters: {'page': page, 'includeSpaces': true, 'size': 25, 'search': search},
|
||||||
|
expectedResponseModel: (json) {
|
||||||
|
try {
|
||||||
|
List<dynamic> jsonData = json['data'] ?? [];
|
||||||
|
hasNext = json['hasNext'] ?? false;
|
||||||
|
int currentPage = json['page'] ?? 1;
|
||||||
|
List<CommunityModel> communityList = jsonData.map((jsonItem) {
|
||||||
|
return CommunityModel.fromJson(jsonItem);
|
||||||
|
}).toList();
|
||||||
|
|
||||||
|
page = currentPage + 1;
|
||||||
|
paginationModel = PaginationModel(
|
||||||
|
pageNum: page, hasNext: hasNext, size: 25, communities: communityList);
|
||||||
|
return paginationModel;
|
||||||
|
} catch (_) {
|
||||||
|
hasNext = false;
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
} catch (_) {}
|
||||||
|
return paginationModel;
|
||||||
|
}
|
||||||
|
|
||||||
Future<CommunityModel?> getCommunityById(String communityId) async {
|
Future<CommunityModel?> getCommunityById(String communityId) async {
|
||||||
try {
|
try {
|
||||||
final response = await HTTPService().get(
|
final response = await HTTPService().get(
|
||||||
|
Reference in New Issue
Block a user