addign tag model

This commit is contained in:
hannathkadher
2025-01-05 23:22:30 +04:00
parent 0fda5457ae
commit a31eb27c92
13 changed files with 190 additions and 102 deletions

View File

@ -28,16 +28,36 @@ class AssignTagModelsDialog extends StatefulWidget {
class AssignTagModelsDialogState extends State<AssignTagModelsDialog> {
late List<TagModel> tags;
late List<SelectedProduct> selectedProducts;
late List<String> 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<AssignTagModelsDialog> {
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<String>(
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<String>(
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<String>(
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<String>(
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(),
),
),
),
),

View File

@ -329,7 +329,6 @@ class SpaceManagementBloc
Emitter<SpaceManagementState> emit,
) {
final communities = List<CommunityModel>.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<CommunityModel> communities = await _api.fetchCommunities();
List<CommunityModel> updatedCommunities = await Future.wait(
communities.map((community) async {
List<SpaceModel> spaces =

View File

@ -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<String, dynamic> toJson() {
return {

View File

@ -20,7 +20,6 @@ class SpaceModel {
Offset position;
bool isHovered;
SpaceStatus status;
List<SelectedProduct> selectedProducts;
String internalId;
List<Connection> 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<String, dynamic> 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 &&

View File

@ -114,7 +114,7 @@ class _AddDeviceWidgetState extends State<AddDeviceWidget> {
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<AddDeviceWidget> {
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;
}

View File

@ -299,7 +299,7 @@ class _CommunityStructureAreaState extends State<CommunityStructureArea> {
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<CommunityStructureArea> {
icon: space.icon,
editSpace: space,
isEdit: true,
selectedProducts: space.selectedProducts,
onCreateSpace: (String name, String icon,
List<SelectedProduct> 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

View File

@ -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<TagModel>? tags;

View File

@ -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<String, dynamic> json) {
final String internalId = json['internalId'] ?? const Uuid().v4();

View File

@ -13,19 +13,19 @@ class AddDeviceTypeModelBloc
UpdateProductCountEvent event, Emitter<List<SelectedProduct>> 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();

View File

@ -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<Object> get props => [productId, count];

View File

@ -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<AddDeviceTypeModelBloc>().add(
UpdateProductCountEvent(
productId: product.uuid, count: newCount,productName: product.catName),
productId: product.uuid,
count: newCount,
productName: product.catName,
product: product),
);
},
),

View File

@ -167,7 +167,6 @@ class CommunitySpaceManagementApi {
bool isPrivate = false,
required Offset position,
String? icon,
required List<SelectedProduct> 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<SelectedProduct> 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;

View File

@ -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;