mirror of
https://github.com/SyncrowIOT/web.git
synced 2025-07-10 07:07:19 +00:00
addign tag model
This commit is contained in:
@ -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(),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
@ -330,7 +330,6 @@ class SpaceManagementBloc
|
||||
) {
|
||||
final communities = List<CommunityModel>.from(previousState.communities);
|
||||
|
||||
|
||||
for (var community in communities) {
|
||||
if (community.uuid == communityUuid) {
|
||||
community.spaces = allSpaces;
|
||||
@ -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) {
|
||||
|
@ -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 {
|
||||
|
@ -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 &&
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
@ -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];
|
||||
|
@ -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),
|
||||
);
|
||||
},
|
||||
),
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
Reference in New Issue
Block a user