diff --git a/lib/pages/spaces_management/tag_model/bloc/add_device_model_bloc.dart b/lib/pages/spaces_management/tag_model/bloc/add_device_model_bloc.dart index 3091d152..9c617a12 100644 --- a/lib/pages/spaces_management/tag_model/bloc/add_device_model_bloc.dart +++ b/lib/pages/spaces_management/tag_model/bloc/add_device_model_bloc.dart @@ -1,38 +1,75 @@ import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/selected_product_model.dart'; +import 'package:syncrow_web/pages/spaces_management/tag_model/bloc/add_device_model_state.dart'; import 'package:syncrow_web/pages/spaces_management/tag_model/bloc/add_device_type_model_event.dart'; class AddDeviceTypeModelBloc - extends Bloc> { - AddDeviceTypeModelBloc(List initialProducts) - : super(initialProducts) { + extends Bloc { + AddDeviceTypeModelBloc() : super(AddDeviceModelInitial()) { + on(_onInitializeTagModels); on(_onUpdateProductCount); } - void _onUpdateProductCount( - UpdateProductCountEvent event, Emitter> emit) { - final existingProduct = state.firstWhere( - (p) => p.productId == event.productId, - orElse: () => SelectedProduct(productId: event.productId, count: 0,productName: event.productName,product: event.product ), - ); + void _onInitializeTagModels( + InitializeDeviceTypeModel event, Emitter emit) { + emit(AddDeviceModelLoaded( + selectedProducts: event.addedProducts, + initialTag: event.initialTags, + )); + } - if (event.count > 0) { - if (!state.contains(existingProduct)) { - emit([ - ...state, - SelectedProduct(productId: event.productId, count: event.count, productName: event.productName, product: event.product) - ]); + void _onUpdateProductCount( + UpdateProductCountEvent event, Emitter emit) { + final currentState = state; + + if (currentState is AddDeviceModelLoaded) { + final existingProduct = currentState.selectedProducts.firstWhere( + (p) => p.productId == event.productId, + orElse: () => SelectedProduct( + productId: event.productId, + count: 0, + productName: event.productName, + product: event.product, + ), + ); + + List updatedProducts; + + if (event.count > 0) { + if (!currentState.selectedProducts.contains(existingProduct)) { + updatedProducts = [ + ...currentState.selectedProducts, + SelectedProduct( + productId: event.productId, + count: event.count, + productName: event.productName, + product: event.product, + ), + ]; + } else { + updatedProducts = currentState.selectedProducts.map((p) { + if (p.productId == event.productId) { + return SelectedProduct( + productId: p.productId, + count: event.count, + productName: p.productName, + product: p.product, + ); + } + return p; + }).toList(); + } } else { - final updatedList = state.map((p) { - if (p.productId == event.productId) { - return SelectedProduct(productId: p.productId, count: event.count, productName: p.productName,product: p.product); - } - return p; - }).toList(); - emit(updatedList); + // Remove the product if the count is 0 + updatedProducts = currentState.selectedProducts + .where((p) => p.productId != event.productId) + .toList(); } - } else { - emit(state.where((p) => p.productId != event.productId).toList()); + + // Emit the updated state + emit(AddDeviceModelLoaded( + selectedProducts: updatedProducts, + initialTag: currentState.initialTag)); } } } diff --git a/lib/pages/spaces_management/tag_model/bloc/add_device_model_state.dart b/lib/pages/spaces_management/tag_model/bloc/add_device_model_state.dart new file mode 100644 index 00000000..f45471cd --- /dev/null +++ b/lib/pages/spaces_management/tag_model/bloc/add_device_model_state.dart @@ -0,0 +1,36 @@ +import 'package:equatable/equatable.dart'; +import 'package:syncrow_web/pages/spaces_management/all_spaces/model/selected_product_model.dart'; +import 'package:syncrow_web/pages/spaces_management/space_model/models/tag_model.dart'; + +abstract class AddDeviceModelState extends Equatable { + const AddDeviceModelState(); + + @override + List get props => []; +} + +class AddDeviceModelInitial extends AddDeviceModelState {} + +class AddDeviceModelLoading extends AddDeviceModelState {} + +class AddDeviceModelLoaded extends AddDeviceModelState { + final List selectedProducts; + final List initialTag; + + const AddDeviceModelLoaded({ + required this.selectedProducts, + required this.initialTag, + }); + + @override + List get props => [selectedProducts, initialTag]; +} + +class AddDeviceModelError extends AddDeviceModelState { + final String errorMessage; + + const AddDeviceModelError(this.errorMessage); + + @override + List get props => [errorMessage]; +} diff --git a/lib/pages/spaces_management/tag_model/bloc/add_device_type_model_event.dart b/lib/pages/spaces_management/tag_model/bloc/add_device_type_model_event.dart index 1d6976f8..9b3a8b1e 100644 --- a/lib/pages/spaces_management/tag_model/bloc/add_device_type_model_event.dart +++ b/lib/pages/spaces_management/tag_model/bloc/add_device_type_model_event.dart @@ -1,11 +1,16 @@ import 'package:equatable/equatable.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/product_model.dart'; +import 'package:syncrow_web/pages/spaces_management/all_spaces/model/selected_product_model.dart'; +import 'package:syncrow_web/pages/spaces_management/space_model/models/tag_model.dart'; abstract class AddDeviceTypeModelEvent extends Equatable { + const AddDeviceTypeModelEvent(); + @override List get props => []; } + class UpdateProductCountEvent extends AddDeviceTypeModelEvent { final String productId; final int count; @@ -17,3 +22,17 @@ class UpdateProductCountEvent extends AddDeviceTypeModelEvent { @override List get props => [productId, count]; } + + +class InitializeDeviceTypeModel extends AddDeviceTypeModelEvent { + final List initialTags; + final List addedProducts; + + const InitializeDeviceTypeModel({ + this.initialTags = const [], + required this.addedProducts, + }); + + @override + List get props => [initialTags, addedProducts]; +} diff --git a/lib/pages/spaces_management/tag_model/views/add_device_type_model_widget.dart b/lib/pages/spaces_management/tag_model/views/add_device_type_model_widget.dart index f7f4c3f7..ea0a94a6 100644 --- a/lib/pages/spaces_management/tag_model/views/add_device_type_model_widget.dart +++ b/lib/pages/spaces_management/tag_model/views/add_device_type_model_widget.dart @@ -9,6 +9,8 @@ import 'package:syncrow_web/pages/spaces_management/space_model/models/subspace_ import 'package:syncrow_web/pages/spaces_management/space_model/models/tag_model.dart'; import 'package:syncrow_web/pages/spaces_management/space_model/widgets/dialog/create_space_model_dialog.dart'; import 'package:syncrow_web/pages/spaces_management/tag_model/bloc/add_device_model_bloc.dart'; +import 'package:syncrow_web/pages/spaces_management/tag_model/bloc/add_device_model_state.dart'; +import 'package:syncrow_web/pages/spaces_management/tag_model/bloc/add_device_type_model_event.dart'; import 'package:syncrow_web/pages/spaces_management/tag_model/widgets/action_button_widget.dart'; import 'package:syncrow_web/pages/spaces_management/tag_model/widgets/scrollable_grid_view_widget.dart'; import 'package:syncrow_web/utils/color_manager.dart'; @@ -21,14 +23,15 @@ class AddDeviceTypeModelWidget extends StatelessWidget { final List? allTags; final String spaceName; - const AddDeviceTypeModelWidget( - {super.key, - this.products, - this.initialSelectedProducts, - this.subspaces, - this.allTags, - this.spaceTagModels, - required this.spaceName}); + const AddDeviceTypeModelWidget({ + super.key, + this.products, + this.initialSelectedProducts, + this.subspaces, + this.allTags, + this.spaceTagModels, + required this.spaceName, + }); @override Widget build(BuildContext context) { @@ -40,91 +43,108 @@ class AddDeviceTypeModelWidget extends StatelessWidget { : 3; return BlocProvider( - create: (_) => AddDeviceTypeModelBloc(initialSelectedProducts ?? []), - child: Builder( - builder: (context) => AlertDialog( - title: const Text('Add Devices'), - backgroundColor: ColorsManager.whiteColors, - content: SingleChildScrollView( - child: Container( - width: size.width * 0.9, - height: size.height * 0.65, - color: ColorsManager.textFieldGreyColor, - child: Column( - children: [ - const SizedBox(height: 16), - Expanded( - child: Padding( - padding: const EdgeInsets.symmetric(horizontal: 20.0), - child: ScrollableGridViewWidget( - products: products, crossAxisCount: crossAxisCount), - ), + create: (_) => AddDeviceTypeModelBloc() + ..add(InitializeDeviceTypeModel( + initialTags: spaceTagModels ?? [], + addedProducts: initialSelectedProducts ?? [], + )), + child: Builder( + builder: (context) => AlertDialog( + title: const Text('Add Devices'), + backgroundColor: ColorsManager.whiteColors, + content: BlocBuilder( + builder: (context, state) { + if (state is AddDeviceModelLoading) { + return const Center(child: CircularProgressIndicator()); + } + if (state is AddDeviceModelLoaded) { + return SingleChildScrollView( + child: Container( + width: size.width * 0.9, + height: size.height * 0.65, + color: ColorsManager.textFieldGreyColor, + child: Column( + children: [ + const SizedBox(height: 16), + Expanded( + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 20.0), + child: ScrollableGridViewWidget( + products: products, + crossAxisCount: crossAxisCount, + initialProductCounts: state.selectedProducts, + ), + ), + ), + ], ), - ], + ), + ); + } + return const SizedBox(); + }, + ), + actions: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + CancelButton( + label: 'Cancel', + onPressed: () async { + Navigator.of(context).pop(); + await showDialog( + barrierDismissible: false, + context: context, + builder: (context) => CreateSpaceModelDialog( + products: products, + allTags: allTags, + spaceModel: SpaceTemplateModel( + modelName: spaceName, + subspaceModels: subspaces, + tags: spaceTagModels, + ), + ), + ); + }, ), - ), - ), - actions: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - CancelButton( - label: 'Cancel', - onPressed: () async { - Navigator.of(context).pop(); - await showDialog( + ActionButton( + label: 'Continue', + backgroundColor: ColorsManager.secondaryColor, + foregroundColor: ColorsManager.whiteColors, + onPressed: () async { + final state = context.read().state; + if (state is AddDeviceModelLoaded && + state.selectedProducts.isNotEmpty) { + final initialTags = generateInitialTags( + spaceTagModels: spaceTagModels, + subspaces: subspaces, + ); + + final dialogTitle = initialTags.isNotEmpty + ? 'Edit Device' + : 'Assign Tags'; + await showDialog( barrierDismissible: false, context: context, - builder: (context) => CreateSpaceModelDialog( - products: products, - allTags: allTags, - spaceModel: SpaceTemplateModel( - modelName: spaceName, - subspaceModels: subspaces, - tags: spaceTagModels, - )), - ); - }, - ), - ActionButton( - label: 'Continue', - backgroundColor: ColorsManager.secondaryColor, - foregroundColor: ColorsManager.whiteColors, - onPressed: () async { - final currentState = - context.read().state; - Navigator.of(context).pop(); - - if (currentState.isNotEmpty) { - final initialTags = generateInitialTags( - spaceTagModels: spaceTagModels, + builder: (context) => AssignTagModelsDialog( + products: products, subspaces: subspaces, - ); - - final dialogTitle = initialTags.isNotEmpty - ? 'Edit Device' - : 'Assign Tags'; - await showDialog( - barrierDismissible: false, - context: context, - builder: (context) => AssignTagModelsDialog( - products: products, - subspaces: subspaces, - addedProducts: currentState, - allTags: allTags, - spaceName: spaceName, - initialTags: initialTags, - title: dialogTitle, - ), - ); - } - }, - ), - ], - ), - ], - ), - )); + addedProducts: state.selectedProducts, + allTags: allTags, + spaceName: spaceName, + initialTags: state.initialTag, + title: dialogTitle, + ), + ); + } + }, + ), + ], + ), + ], + ), + ), + ); } List generateInitialTags({ diff --git a/lib/pages/spaces_management/tag_model/widgets/scrollable_grid_view_widget.dart b/lib/pages/spaces_management/tag_model/widgets/scrollable_grid_view_widget.dart index 2a653dde..3e32ccd8 100644 --- a/lib/pages/spaces_management/tag_model/widgets/scrollable_grid_view_widget.dart +++ b/lib/pages/spaces_management/tag_model/widgets/scrollable_grid_view_widget.dart @@ -3,6 +3,7 @@ import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/product_model.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/selected_product_model.dart'; import 'package:syncrow_web/pages/spaces_management/tag_model/bloc/add_device_model_bloc.dart'; +import 'package:syncrow_web/pages/spaces_management/tag_model/bloc/add_device_model_state.dart'; import 'package:syncrow_web/pages/spaces_management/tag_model/widgets/device_type_tile_widget.dart'; class ScrollableGridViewWidget extends StatelessWidget { @@ -24,8 +25,12 @@ class ScrollableGridViewWidget extends StatelessWidget { return Scrollbar( controller: scrollController, thumbVisibility: true, - child: BlocBuilder>( - builder: (context, productCounts) { + child: BlocBuilder( + builder: (context, state) { + final productCounts = state is AddDeviceModelLoaded + ? state.selectedProducts + : []; + return GridView.builder( controller: scrollController, shrinkWrap: true,