diff --git a/lib/pages/spaces_management/all_spaces/assign_tag_models/views/assign_tag_models_dialog.dart b/lib/pages/spaces_management/all_spaces/assign_tag_models/views/assign_tag_models_dialog.dart index acdb75d8..885f483b 100644 --- a/lib/pages/spaces_management/all_spaces/assign_tag_models/views/assign_tag_models_dialog.dart +++ b/lib/pages/spaces_management/all_spaces/assign_tag_models/views/assign_tag_models_dialog.dart @@ -28,16 +28,36 @@ class AssignTagModelsDialog extends StatefulWidget { class AssignTagModelsDialogState extends State { late List tags; late List selectedProducts; + late List locations; @override void initState() { super.initState(); + print(widget.addedProducts); + print(widget.subspaces); - if (widget.products != null) { - print(widget.products); - tags = []; - } + // Initialize tags from widget.initialTags or create new ones if it's empty + tags = widget.initialTags?.isNotEmpty == true + ? widget.initialTags! + : widget.addedProducts + .expand((selectedProduct) => List.generate( + selectedProduct.count, // Generate `count` number of tags + (index) => TagModel( + tag: '', // Initialize each tag with a default value + product: selectedProduct.product, + location: 'None', // Default location + ), + )) + .toList(); + + // Initialize selected products selectedProducts = widget.addedProducts; + + // Initialize locations from subspaces or empty list if null + locations = widget.subspaces != null + ? widget.subspaces!.map((subspace) => subspace.subspaceName).toList() + : []; + locations.add("None"); } @override @@ -47,51 +67,121 @@ class AssignTagModelsDialogState extends State { backgroundColor: ColorsManager.whiteColors, content: SingleChildScrollView( child: Container( - width: MediaQuery.of(context).size.width * 0.9, - child: DataTable( - columns: const [ - DataColumn(label: Text('#')), - DataColumn(label: Text('Device')), - DataColumn(label: Text('Tag')), - DataColumn(label: Text('Location')), - ], - rows: selectedProducts.asMap().entries.map((entry) { - final index = entry.key + 1; - final selectedProduct = entry.value; - return DataRow(cells: [ - DataCell(Text(index.toString())), - DataCell(Text(selectedProduct.productName ?? 'Unknown')), - DataCell( - DropdownButton( - value: - 'Tag 1', // Static text that matches an item in the list - onChanged: (value) { - // Handle value change if needed - }, - items: List.generate(10, (index) { - final tag = 'Tag ${index + 1}'; - return DropdownMenuItem(value: tag, child: Text(tag)); - }), - ), + width: MediaQuery.of(context).size.width * 0.4, + decoration: BoxDecoration( + border: Border.all(color: ColorsManager.dataHeaderGrey, width: 1), + borderRadius: BorderRadius.circular(20), + ), + child: Theme( + data: Theme.of(context).copyWith( + dataTableTheme: DataTableThemeData( + headingRowColor: + MaterialStateProperty.all(ColorsManager.dataHeaderGrey), + headingTextStyle: const TextStyle( + color: ColorsManager.blackColor, + fontWeight: FontWeight.bold, ), - DataCell( - DropdownButton( - value: widget.subspaces?.isNotEmpty == true - ? widget.subspaces!.first.subspaceName - : null, - onChanged: (value) { - // Handle value changes here - }, - items: widget.subspaces! - .map((subspace) => DropdownMenuItem( - value: subspace.subspaceName, - child: Text(subspace.subspaceName), - )) - .toList(), - ), - ), - ]); - }).toList(), + ), + ), + child: DataTable( + border: TableBorder.all( + color: ColorsManager.dataHeaderGrey, + width: 1, + borderRadius: BorderRadius.circular(20), + ), + columns: const [ + DataColumn(label: Text('#')), + DataColumn(label: Text('Device')), + DataColumn(label: Text('Tag')), + DataColumn(label: Text('Location')), + ], + rows: tags.asMap().entries.map((entry) { + final index = entry.key + 1; + final tag = entry.value; + + return DataRow( + cells: [ + DataCell( + Center( + child: Text(index.toString()), + ), + ), + DataCell( + Center( + child: Text(tag.product?.catName ?? 'Unknown'), + ), + ), + DataCell( + Center( + child: DropdownButton( + value: tag.tag!.isNotEmpty ? tag.tag : null, + onChanged: (value) { + setState(() { + tag.tag = value ?? ''; // Update tag value + }); + }, + items: [ + const DropdownMenuItem( + value: null, + child: Text('None'), + ), + ...List.generate(10, (index) { + final tagName = 'Tag ${index + 1}'; + return DropdownMenuItem( + value: tagName, + child: Text(tagName), + ); + }), + ], + ), + ), + ), + DataCell( + Center( + child: DropdownButtonHideUnderline( + child: DropdownButton( + alignment: AlignmentDirectional.centerEnd, + value: locations.contains(tag.location) + ? tag.location + : null, // Validate value + onChanged: (value) { + setState(() { + tag.location = + value ?? 'None'; // Update location + }); + }, + dropdownColor: Colors.white, + icon: const Icon( + Icons.arrow_drop_down, + color: Colors.black, + ), + style: const TextStyle( + fontSize: 16, + fontWeight: FontWeight.w600, + color: Colors.black, + ), + isExpanded: true, + items: locations + .map((location) => DropdownMenuItem( + value: location, + child: Text( + location, + style: const TextStyle( + fontSize: 14, + fontWeight: FontWeight.w400, + color: Colors.grey, + ), + ), + )) + .toList(), + ), + ), + ), + ), + ], + ); + }).toList(), + ), ), ), ), 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 0c002e7d..2b749a32 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 @@ -329,7 +329,6 @@ class SpaceManagementBloc Emitter emit, ) { final communities = List.from(previousState.communities); - for (var community in communities) { if (community.uuid == communityUuid) { @@ -367,26 +366,26 @@ class SpaceManagementBloc try { if (space.uuid != null && space.uuid!.isNotEmpty) { final response = await _api.updateSpace( - communityId: communityUuid, - spaceId: space.uuid!, - name: space.name, - parentId: space.parent?.uuid, - isPrivate: space.isPrivate, - position: space.position, - icon: space.icon, - direction: space.incomingConnection?.direction, - products: space.selectedProducts); + communityId: communityUuid, + spaceId: space.uuid!, + name: space.name, + parentId: space.parent?.uuid, + isPrivate: space.isPrivate, + position: space.position, + icon: space.icon, + direction: space.incomingConnection?.direction, + ); } else { // Call create if the space does not have a UUID final response = await _api.createSpace( - communityId: communityUuid, - name: space.name, - parentId: space.parent?.uuid, - isPrivate: space.isPrivate, - position: space.position, - icon: space.icon, - direction: space.incomingConnection?.direction, - products: space.selectedProducts); + communityId: communityUuid, + name: space.name, + parentId: space.parent?.uuid, + isPrivate: space.isPrivate, + position: space.position, + icon: space.icon, + direction: space.incomingConnection?.direction, + ); space.uuid = response?.uuid; } } catch (e) { @@ -426,7 +425,7 @@ class SpaceManagementBloc emit(SpaceManagementLoading()); try { List communities = await _api.fetchCommunities(); - + List updatedCommunities = await Future.wait( communities.map((community) async { List spaces = diff --git a/lib/pages/spaces_management/all_spaces/model/selected_product_model.dart b/lib/pages/spaces_management/all_spaces/model/selected_product_model.dart index 31d7f6f8..91314e42 100644 --- a/lib/pages/spaces_management/all_spaces/model/selected_product_model.dart +++ b/lib/pages/spaces_management/all_spaces/model/selected_product_model.dart @@ -1,9 +1,12 @@ +import 'package:syncrow_web/pages/spaces_management/all_spaces/model/product_model.dart'; + class SelectedProduct { final String productId; int count; final String productName; + final ProductModel? product; - SelectedProduct({required this.productId, required this.count, required this.productName}); + SelectedProduct({required this.productId, required this.count, required this.productName, this.product}); Map toJson() { return { 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 7406d919..4bdf4ece 100644 --- a/lib/pages/spaces_management/all_spaces/model/space_model.dart +++ b/lib/pages/spaces_management/all_spaces/model/space_model.dart @@ -20,7 +20,6 @@ class SpaceModel { Offset position; bool isHovered; SpaceStatus status; - List selectedProducts; String internalId; List outgoingConnections = []; // Connections from this space @@ -41,7 +40,6 @@ class SpaceModel { this.isHovered = false, this.incomingConnection, this.status = SpaceStatus.unchanged, - this.selectedProducts = const [], }) : internalId = internalId ?? const Uuid().v4(); factory SpaceModel.fromJson(Map json, @@ -85,15 +83,6 @@ class SpaceModel { icon: json['icon'] ?? Assets.location, position: Offset(json['x'] ?? 0, json['y'] ?? 0), isHovered: false, - selectedProducts: json['spaceProducts'] != null - ? (json['spaceProducts'] as List).map((product) { - return SelectedProduct( - productId: product['product']['uuid'], - count: product['productCount'], - productName: '', - ); - }).toList() - : [], ); if (json['incomingConnections'] != null && diff --git a/lib/pages/spaces_management/all_spaces/widgets/add_device_type_widget.dart b/lib/pages/spaces_management/all_spaces/widgets/add_device_type_widget.dart index ed764250..93a38716 100644 --- a/lib/pages/spaces_management/all_spaces/widgets/add_device_type_widget.dart +++ b/lib/pages/spaces_management/all_spaces/widgets/add_device_type_widget.dart @@ -114,7 +114,7 @@ class _AddDeviceWidgetState extends State { Widget _buildDeviceTypeTile(ProductModel product, Size size) { final selectedProduct = productCounts.firstWhere( (p) => p.productId == product.uuid, - orElse: () => SelectedProduct(productId: product.uuid, count: 0, productName: product.catName), + orElse: () => SelectedProduct(productId: product.uuid, count: 0, productName: product.catName, product: product), ); return SizedBox( @@ -143,7 +143,7 @@ class _AddDeviceWidgetState extends State { if (newCount > 0) { if (!productCounts.contains(selectedProduct)) { productCounts - .add(SelectedProduct(productId: product.uuid, count: newCount, productName: product.catName)); + .add(SelectedProduct(productId: product.uuid, count: newCount, productName: product.catName, product: product)); } else { selectedProduct.count = newCount; } 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 c11563da..a929c6fd 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 @@ -299,7 +299,7 @@ class _CommunityStructureAreaState extends State { isPrivate: false, children: [], status: SpaceStatus.newSpace, - selectedProducts: selectedProducts); + ); if (parentIndex != null && direction != null) { SpaceModel parentSpace = spaces[parentIndex]; @@ -335,14 +335,12 @@ class _CommunityStructureAreaState extends State { icon: space.icon, editSpace: space, isEdit: true, - selectedProducts: space.selectedProducts, onCreateSpace: (String name, String icon, List selectedProducts) { setState(() { // Update the space's properties space.name = name; space.icon = icon; - space.selectedProducts = selectedProducts; if (space.status != SpaceStatus.newSpace) { space.status = SpaceStatus.modified; // Mark as modified diff --git a/lib/pages/spaces_management/space_model/models/subspace_template_model.dart b/lib/pages/spaces_management/space_model/models/subspace_template_model.dart index 8f9d4d4d..911494a0 100644 --- a/lib/pages/spaces_management/space_model/models/subspace_template_model.dart +++ b/lib/pages/spaces_management/space_model/models/subspace_template_model.dart @@ -2,7 +2,7 @@ import 'package:syncrow_web/pages/spaces_management/space_model/models/tag_model class SubspaceTemplateModel { final String? uuid; - final String subspaceName; + String subspaceName; final bool disabled; final List? tags; diff --git a/lib/pages/spaces_management/space_model/models/tag_model.dart b/lib/pages/spaces_management/space_model/models/tag_model.dart index 820b9515..1e7c594b 100644 --- a/lib/pages/spaces_management/space_model/models/tag_model.dart +++ b/lib/pages/spaces_management/space_model/models/tag_model.dart @@ -1,18 +1,21 @@ import 'package:syncrow_web/pages/spaces_management/all_spaces/model/product_model.dart'; +import 'package:syncrow_web/pages/spaces_management/space_model/models/subspace_template_model.dart'; import 'package:uuid/uuid.dart'; class TagModel { String? uuid; - String tag; + String? tag; final ProductModel? product; String internalId; + String? location; - TagModel({ - this.uuid, - required this.tag, - this.product, - String? internalId, - }) : internalId = internalId ?? const Uuid().v4(); + TagModel( + {this.uuid, + required this.tag, + this.product, + String? internalId, + this.location}) + : internalId = internalId ?? const Uuid().v4(); factory TagModel.fromJson(Map json) { final String internalId = json['internalId'] ?? const Uuid().v4(); 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 1049fdce..3091d152 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 @@ -13,19 +13,19 @@ class AddDeviceTypeModelBloc UpdateProductCountEvent event, Emitter> emit) { final existingProduct = state.firstWhere( (p) => p.productId == event.productId, - orElse: () => SelectedProduct(productId: event.productId, count: 0,productName: event.productName ), + orElse: () => SelectedProduct(productId: event.productId, count: 0,productName: event.productName,product: event.product ), ); if (event.count > 0) { if (!state.contains(existingProduct)) { emit([ ...state, - SelectedProduct(productId: event.productId, count: event.count, productName: event.productName) + SelectedProduct(productId: event.productId, count: event.count, productName: event.productName, product: event.product) ]); } else { final updatedList = state.map((p) { if (p.productId == event.productId) { - return SelectedProduct(productId: p.productId, count: event.count, productName: p.productName); + return SelectedProduct(productId: p.productId, count: event.count, productName: p.productName,product: p.product); } return p; }).toList(); 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 c9594020..1d6976f8 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,4 +1,5 @@ import 'package:equatable/equatable.dart'; +import 'package:syncrow_web/pages/spaces_management/all_spaces/model/product_model.dart'; abstract class AddDeviceTypeModelEvent extends Equatable { @override @@ -9,8 +10,9 @@ class UpdateProductCountEvent extends AddDeviceTypeModelEvent { final String productId; final int count; final String productName; + final ProductModel product; - UpdateProductCountEvent({required this.productId, required this.count, required this.productName}); + UpdateProductCountEvent({required this.productId, required this.count, required this.productName, required this.product}); @override List get props => [productId, count]; diff --git a/lib/pages/spaces_management/tag_model/widgets/device_type_tile_widget.dart b/lib/pages/spaces_management/tag_model/widgets/device_type_tile_widget.dart index 38159057..c2d38d0b 100644 --- a/lib/pages/spaces_management/tag_model/widgets/device_type_tile_widget.dart +++ b/lib/pages/spaces_management/tag_model/widgets/device_type_tile_widget.dart @@ -24,7 +24,11 @@ class DeviceTypeTileWidget extends StatelessWidget { Widget build(BuildContext context) { final selectedProduct = productCounts.firstWhere( (p) => p.productId == product.uuid, - orElse: () => SelectedProduct(productId: product.uuid, count: 0, productName: product.catName), + orElse: () => SelectedProduct( + productId: product.uuid, + count: 0, + productName: product.catName, + product: product), ); return Card( @@ -48,7 +52,10 @@ class DeviceTypeTileWidget extends StatelessWidget { onCountChanged: (newCount) { context.read().add( UpdateProductCountEvent( - productId: product.uuid, count: newCount,productName: product.catName), + productId: product.uuid, + count: newCount, + productName: product.catName, + product: product), ); }, ), diff --git a/lib/services/space_mana_api.dart b/lib/services/space_mana_api.dart index def94441..333b715e 100644 --- a/lib/services/space_mana_api.dart +++ b/lib/services/space_mana_api.dart @@ -167,7 +167,6 @@ class CommunitySpaceManagementApi { bool isPrivate = false, required Offset position, String? icon, - required List products, }) async { try { final body = { @@ -177,7 +176,6 @@ class CommunitySpaceManagementApi { 'y': position.dy, 'direction': direction, 'icon': icon, - 'products': products.map((product) => product.toJson()).toList(), }; if (parentId != null) { body['parentUuid'] = parentId; @@ -207,7 +205,6 @@ class CommunitySpaceManagementApi { String? direction, bool isPrivate = false, required Offset position, - required List products, }) async { try { final body = { @@ -217,7 +214,6 @@ class CommunitySpaceManagementApi { 'y': position.dy, 'direction': direction, 'icon': icon, - 'products': products.map((product) => product.toJson()).toList(), }; if (parentId != null) { body['parentUuid'] = parentId; diff --git a/lib/utils/color_manager.dart b/lib/utils/color_manager.dart index 8d0aae43..eaf1e6b1 100644 --- a/lib/utils/color_manager.dart +++ b/lib/utils/color_manager.dart @@ -56,5 +56,6 @@ abstract class ColorsManager { static const Color CircleImageBackground = Color(0xFFF4F4F4); static const Color softGray = Color(0xFFD5D5D5); static const Color semiTransparentBlack = Color(0x19000000); + static const Color dataHeaderGrey = Color(0x33999999); } //background: #background: #5D5D5D;