mirror of
https://github.com/SyncrowIOT/web.git
synced 2025-11-27 03:54:56 +00:00
device type select
This commit is contained in:
@ -0,0 +1,38 @@
|
|||||||
|
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/add_device_type/bloc/add_device_type_model_event.dart';
|
||||||
|
|
||||||
|
class AddDeviceTypeBloc
|
||||||
|
extends Bloc<AddDeviceTypeEvent, List<SelectedProduct>> {
|
||||||
|
AddDeviceTypeBloc(List<SelectedProduct> initialProducts)
|
||||||
|
: super(initialProducts) {
|
||||||
|
on<UpdateProductCountEvent>(_onUpdateProductCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _onUpdateProductCount(
|
||||||
|
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,product: event.product ),
|
||||||
|
);
|
||||||
|
|
||||||
|
if (event.count > 0) {
|
||||||
|
if (!state.contains(existingProduct)) {
|
||||||
|
emit([
|
||||||
|
...state,
|
||||||
|
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,product: p.product);
|
||||||
|
}
|
||||||
|
return p;
|
||||||
|
}).toList();
|
||||||
|
emit(updatedList);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
emit(state.where((p) => p.productId != event.productId).toList());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,19 @@
|
|||||||
|
import 'package:equatable/equatable.dart';
|
||||||
|
import 'package:syncrow_web/pages/spaces_management/all_spaces/model/product_model.dart';
|
||||||
|
|
||||||
|
abstract class AddDeviceTypeEvent extends Equatable {
|
||||||
|
@override
|
||||||
|
List<Object> get props => [];
|
||||||
|
}
|
||||||
|
|
||||||
|
class UpdateProductCountEvent extends AddDeviceTypeEvent {
|
||||||
|
final String productId;
|
||||||
|
final int count;
|
||||||
|
final String productName;
|
||||||
|
final ProductModel product;
|
||||||
|
|
||||||
|
UpdateProductCountEvent({required this.productId, required this.count, required this.productName, required this.product});
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<Object> get props => [productId, count];
|
||||||
|
}
|
||||||
@ -0,0 +1,130 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
import 'package:syncrow_web/pages/common/buttons/cancel_button.dart';
|
||||||
|
import 'package:syncrow_web/pages/spaces_management/add_device_type/widgets/scrollable_grid_view_widget.dart';
|
||||||
|
import 'package:syncrow_web/pages/spaces_management/all_spaces/model/subspace_model.dart';
|
||||||
|
import 'package:syncrow_web/pages/spaces_management/all_spaces/model/tag.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/widgets/action_button_widget.dart';
|
||||||
|
import 'package:syncrow_web/utils/color_manager.dart';
|
||||||
|
|
||||||
|
import '../bloc/add_device_model_bloc.dart';
|
||||||
|
|
||||||
|
class AddDeviceTypeWidget extends StatelessWidget {
|
||||||
|
final List<ProductModel>? products;
|
||||||
|
final ValueChanged<List<SelectedProduct>>? onProductsSelected;
|
||||||
|
final List<SelectedProduct>? initialSelectedProducts;
|
||||||
|
final List<SubspaceModel>? subspaces;
|
||||||
|
final List<Tag>? spaceTags;
|
||||||
|
final List<String>? allTags;
|
||||||
|
final String spaceName;
|
||||||
|
|
||||||
|
const AddDeviceTypeWidget(
|
||||||
|
{super.key,
|
||||||
|
this.products,
|
||||||
|
this.initialSelectedProducts,
|
||||||
|
this.onProductsSelected,
|
||||||
|
this.subspaces,
|
||||||
|
this.allTags,
|
||||||
|
this.spaceTags,
|
||||||
|
required this.spaceName});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final size = MediaQuery.of(context).size;
|
||||||
|
final crossAxisCount = size.width > 1200
|
||||||
|
? 8
|
||||||
|
: size.width > 800
|
||||||
|
? 5
|
||||||
|
: 3;
|
||||||
|
|
||||||
|
return BlocProvider(
|
||||||
|
create: (_) => AddDeviceTypeBloc(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),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
actions: [
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
CancelButton(
|
||||||
|
label: 'Cancel',
|
||||||
|
onPressed: () async {
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
},
|
||||||
|
),
|
||||||
|
ActionButton(
|
||||||
|
label: 'Continue',
|
||||||
|
backgroundColor: ColorsManager.secondaryColor,
|
||||||
|
foregroundColor: ColorsManager.whiteColors,
|
||||||
|
onPressed: () async {
|
||||||
|
final currentState =
|
||||||
|
context.read<AddDeviceTypeBloc>().state;
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
|
||||||
|
if (currentState.isNotEmpty) {
|
||||||
|
final initialTags = generateInitialTags(
|
||||||
|
spaceTags: spaceTags,
|
||||||
|
subspaces: subspaces,
|
||||||
|
);
|
||||||
|
|
||||||
|
final dialogTitle = initialTags.isNotEmpty
|
||||||
|
? 'Edit Device'
|
||||||
|
: 'Assign Tags';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Tag> generateInitialTags({
|
||||||
|
List<Tag>? spaceTags,
|
||||||
|
List<SubspaceModel>? subspaces,
|
||||||
|
}) {
|
||||||
|
final List<Tag> initialTags = [];
|
||||||
|
|
||||||
|
if (spaceTags != null) {
|
||||||
|
initialTags.addAll(spaceTags);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (subspaces != null) {
|
||||||
|
for (var subspace in subspaces) {
|
||||||
|
if (subspace.tags != null) {
|
||||||
|
initialTags.addAll(
|
||||||
|
subspace.tags!.map(
|
||||||
|
(tag) => tag.copyWith(location: subspace.subspaceName),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return initialTags;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,67 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
import 'package:syncrow_web/pages/spaces_management/add_device_type/bloc/add_device_model_bloc.dart';
|
||||||
|
import 'package:syncrow_web/pages/spaces_management/add_device_type/bloc/add_device_type_model_event.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/all_spaces/widgets/counter_widget.dart';
|
||||||
|
import 'package:syncrow_web/pages/spaces_management/tag_model/widgets/device_icon_widget.dart';
|
||||||
|
import 'package:syncrow_web/pages/spaces_management/tag_model/widgets/device_name_widget.dart';
|
||||||
|
import 'package:syncrow_web/utils/color_manager.dart';
|
||||||
|
import 'package:syncrow_web/utils/constants/assets.dart';
|
||||||
|
|
||||||
|
class DeviceTypeTileWidget extends StatelessWidget {
|
||||||
|
final ProductModel product;
|
||||||
|
final List<SelectedProduct> productCounts;
|
||||||
|
|
||||||
|
const DeviceTypeTileWidget({
|
||||||
|
super.key,
|
||||||
|
required this.product,
|
||||||
|
required this.productCounts,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final selectedProduct = productCounts.firstWhere(
|
||||||
|
(p) => p.productId == product.uuid,
|
||||||
|
orElse: () => SelectedProduct(
|
||||||
|
productId: product.uuid,
|
||||||
|
count: 0,
|
||||||
|
productName: product.catName,
|
||||||
|
product: product),
|
||||||
|
);
|
||||||
|
|
||||||
|
return Card(
|
||||||
|
elevation: 2,
|
||||||
|
color: ColorsManager.whiteColors,
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.circular(8),
|
||||||
|
),
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.all(4.0),
|
||||||
|
child: Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
DeviceIconWidget(icon: product.icon ?? Assets.doorSensor),
|
||||||
|
const SizedBox(height: 4),
|
||||||
|
DeviceNameWidget(name: product.name),
|
||||||
|
const SizedBox(height: 4),
|
||||||
|
CounterWidget(
|
||||||
|
initialCount: selectedProduct.count,
|
||||||
|
onCountChanged: (newCount) {
|
||||||
|
context.read<AddDeviceTypeBloc>().add(
|
||||||
|
UpdateProductCountEvent(
|
||||||
|
productId: product.uuid,
|
||||||
|
count: newCount,
|
||||||
|
productName: product.catName,
|
||||||
|
product: product),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,70 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
import 'package:syncrow_web/pages/spaces_management/add_device_type/bloc/add_device_model_bloc.dart';
|
||||||
|
import 'package:syncrow_web/pages/spaces_management/add_device_type/widgets/device_type_tile_widget.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';
|
||||||
|
|
||||||
|
class ScrollableGridViewWidget extends StatelessWidget {
|
||||||
|
final List<ProductModel>? products;
|
||||||
|
final int crossAxisCount;
|
||||||
|
final List<SelectedProduct>? initialProductCounts;
|
||||||
|
|
||||||
|
const ScrollableGridViewWidget({
|
||||||
|
super.key,
|
||||||
|
required this.products,
|
||||||
|
required this.crossAxisCount,
|
||||||
|
this.initialProductCounts,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final scrollController = ScrollController();
|
||||||
|
|
||||||
|
return Scrollbar(
|
||||||
|
controller: scrollController,
|
||||||
|
thumbVisibility: true,
|
||||||
|
child: BlocBuilder<AddDeviceTypeBloc, List<SelectedProduct>>(
|
||||||
|
builder: (context, productCounts) {
|
||||||
|
return GridView.builder(
|
||||||
|
controller: scrollController,
|
||||||
|
shrinkWrap: true,
|
||||||
|
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
|
||||||
|
crossAxisCount: crossAxisCount,
|
||||||
|
mainAxisSpacing: 6,
|
||||||
|
crossAxisSpacing: 4,
|
||||||
|
childAspectRatio: .8,
|
||||||
|
),
|
||||||
|
itemCount: products?.length ?? 0,
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
final product = products![index];
|
||||||
|
final initialProductCount = _findInitialProductCount(product);
|
||||||
|
|
||||||
|
return DeviceTypeTileWidget(
|
||||||
|
product: product,
|
||||||
|
productCounts: initialProductCount != null
|
||||||
|
? [...productCounts, initialProductCount]
|
||||||
|
: productCounts,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
SelectedProduct? _findInitialProductCount(ProductModel product) {
|
||||||
|
if (initialProductCounts == null) return null;
|
||||||
|
final matchingProduct = initialProductCounts!.firstWhere(
|
||||||
|
(selectedProduct) => selectedProduct.productId == product.uuid,
|
||||||
|
orElse: () => SelectedProduct(
|
||||||
|
productId: '',
|
||||||
|
count: 0,
|
||||||
|
productName: '',
|
||||||
|
product: null,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
return matchingProduct.productId.isNotEmpty ? matchingProduct : null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:flutter_svg/flutter_svg.dart';
|
import 'package:flutter_svg/flutter_svg.dart';
|
||||||
import 'package:syncrow_web/pages/common/buttons/cancel_button.dart';
|
import 'package:syncrow_web/pages/common/buttons/cancel_button.dart';
|
||||||
import 'package:syncrow_web/pages/common/buttons/default_button.dart';
|
import 'package:syncrow_web/pages/common/buttons/default_button.dart';
|
||||||
|
import 'package:syncrow_web/pages/spaces_management/add_device_type/views/add_device_type_model_widget.dart';
|
||||||
import 'package:syncrow_web/pages/spaces_management/all_spaces/model/product_model.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/all_spaces/model/selected_product_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';
|
||||||
@ -28,6 +29,7 @@ class CreateSpaceDialog extends StatefulWidget {
|
|||||||
final SpaceModel? editSpace;
|
final SpaceModel? editSpace;
|
||||||
final List<SpaceTemplateModel>? spaceModels;
|
final List<SpaceTemplateModel>? spaceModels;
|
||||||
final List<SubspaceModel>? subspaces;
|
final List<SubspaceModel>? subspaces;
|
||||||
|
final List<Tag>? tags;
|
||||||
|
|
||||||
const CreateSpaceDialog(
|
const CreateSpaceDialog(
|
||||||
{super.key,
|
{super.key,
|
||||||
@ -40,7 +42,8 @@ class CreateSpaceDialog extends StatefulWidget {
|
|||||||
this.editSpace,
|
this.editSpace,
|
||||||
this.selectedProducts = const [],
|
this.selectedProducts = const [],
|
||||||
this.spaceModels,
|
this.spaceModels,
|
||||||
this.subspaces});
|
this.subspaces,
|
||||||
|
this.tags});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
CreateSpaceDialogState createState() => CreateSpaceDialogState();
|
CreateSpaceDialogState createState() => CreateSpaceDialogState();
|
||||||
@ -56,6 +59,7 @@ class CreateSpaceDialogState extends State<CreateSpaceDialog> {
|
|||||||
bool isNameFieldInvalid = false;
|
bool isNameFieldInvalid = false;
|
||||||
bool isNameFieldExist = false;
|
bool isNameFieldExist = false;
|
||||||
List<SubspaceModel>? subspaces;
|
List<SubspaceModel>? subspaces;
|
||||||
|
List<Tag>? tags;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
@ -326,7 +330,7 @@ class CreateSpaceDialogState extends State<CreateSpaceDialog> {
|
|||||||
subspaces == null
|
subspaces == null
|
||||||
? DefaultButton(
|
? DefaultButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
_showSubSpaceModelDialog(context, enteredName, [],
|
_showSubSpaceDialog(context, enteredName, [],
|
||||||
false, widget.products, subspaces);
|
false, widget.products, subspaces);
|
||||||
},
|
},
|
||||||
backgroundColor: ColorsManager.textFieldGreyColor,
|
backgroundColor: ColorsManager.textFieldGreyColor,
|
||||||
@ -401,7 +405,7 @@ class CreateSpaceDialogState extends State<CreateSpaceDialog> {
|
|||||||
),
|
),
|
||||||
GestureDetector(
|
GestureDetector(
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
_showSubSpaceModelDialog(
|
_showSubSpaceDialog(
|
||||||
context,
|
context,
|
||||||
enteredName,
|
enteredName,
|
||||||
[],
|
[],
|
||||||
@ -429,19 +433,15 @@ class CreateSpaceDialogState extends State<CreateSpaceDialog> {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 10),
|
const SizedBox(height: 10),
|
||||||
DefaultButton(
|
(tags?.isNotEmpty == true ||
|
||||||
|
subspaces?.any((subspace) =>
|
||||||
|
subspace.tags?.isNotEmpty == true) ==
|
||||||
|
true)
|
||||||
|
? Container()
|
||||||
|
: DefaultButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
showDialog(
|
_showTagCreateDialog(context, enteredName, tags,
|
||||||
context: context,
|
subspaces, widget.products);
|
||||||
builder: (context) => AddDeviceWidget(
|
|
||||||
products: widget.products,
|
|
||||||
onProductsSelected: (selectedProductsMap) {
|
|
||||||
setState(() {
|
|
||||||
selectedProducts = selectedProductsMap;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
),
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
backgroundColor: ColorsManager.textFieldGreyColor,
|
backgroundColor: ColorsManager.textFieldGreyColor,
|
||||||
foregroundColor: Colors.black,
|
foregroundColor: Colors.black,
|
||||||
@ -457,7 +457,8 @@ class CreateSpaceDialogState extends State<CreateSpaceDialog> {
|
|||||||
padding: const EdgeInsets.only(left: 6.0),
|
padding: const EdgeInsets.only(left: 6.0),
|
||||||
child: SvgPicture.asset(
|
child: SvgPicture.asset(
|
||||||
Assets.addIcon,
|
Assets.addIcon,
|
||||||
width: screenWidth * 0.015, // Adjust icon size
|
width: screenWidth *
|
||||||
|
0.015, // Adjust icon size
|
||||||
height: screenWidth * 0.015,
|
height: screenWidth * 0.015,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -465,15 +466,17 @@ class CreateSpaceDialogState extends State<CreateSpaceDialog> {
|
|||||||
Flexible(
|
Flexible(
|
||||||
child: Text(
|
child: Text(
|
||||||
'Add devices',
|
'Add devices',
|
||||||
overflow:
|
overflow: TextOverflow
|
||||||
TextOverflow.ellipsis, // Prevent overflow
|
.ellipsis, // Prevent overflow
|
||||||
style: Theme.of(context).textTheme.bodyMedium,
|
style: Theme.of(context)
|
||||||
|
.textTheme
|
||||||
|
.bodyMedium,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
)
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -560,6 +563,7 @@ class CreateSpaceDialogState extends State<CreateSpaceDialog> {
|
|||||||
if (selectedModel != null) {
|
if (selectedModel != null) {
|
||||||
setState(() {
|
setState(() {
|
||||||
selectedSpaceModel = selectedModel;
|
selectedSpaceModel = selectedModel;
|
||||||
|
subspaces = null;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -568,7 +572,7 @@ class CreateSpaceDialogState extends State<CreateSpaceDialog> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _showSubSpaceModelDialog(
|
void _showSubSpaceDialog(
|
||||||
BuildContext context,
|
BuildContext context,
|
||||||
String name,
|
String name,
|
||||||
final List<Tag>? spaceTags,
|
final List<Tag>? spaceTags,
|
||||||
@ -589,10 +593,68 @@ class CreateSpaceDialogState extends State<CreateSpaceDialog> {
|
|||||||
if (slectedSubspaces != null) {
|
if (slectedSubspaces != null) {
|
||||||
setState(() {
|
setState(() {
|
||||||
subspaces = slectedSubspaces;
|
subspaces = slectedSubspaces;
|
||||||
|
selectedSpaceModel = null;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _showTagCreateDialog(
|
||||||
|
BuildContext context,
|
||||||
|
String name,
|
||||||
|
final List<Tag>? spaceTags,
|
||||||
|
List<SubspaceModel>? subspaces,
|
||||||
|
List<ProductModel>? products) {
|
||||||
|
showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (BuildContext context) {
|
||||||
|
return AddDeviceTypeWidget(
|
||||||
|
spaceName: name,
|
||||||
|
products: products,
|
||||||
|
subspaces: subspaces,
|
||||||
|
spaceTags: spaceTags,
|
||||||
|
allTags: [],
|
||||||
|
initialSelectedProducts:
|
||||||
|
createInitialSelectedProducts(tags, subspaces),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<SelectedProduct> createInitialSelectedProducts(
|
||||||
|
List<Tag>? tags, List<SubspaceModel>? subspaces) {
|
||||||
|
final Map<ProductModel, int> productCounts = {};
|
||||||
|
|
||||||
|
if (tags != null) {
|
||||||
|
for (var tag in tags) {
|
||||||
|
if (tag.product != null) {
|
||||||
|
productCounts[tag.product!] = (productCounts[tag.product!] ?? 0) + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (subspaces != null) {
|
||||||
|
for (var subspace in subspaces) {
|
||||||
|
if (subspace.tags != null) {
|
||||||
|
for (var tag in subspace.tags!) {
|
||||||
|
if (tag.product != null) {
|
||||||
|
productCounts[tag.product!] =
|
||||||
|
(productCounts[tag.product!] ?? 0) + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return productCounts.entries
|
||||||
|
.map((entry) => SelectedProduct(
|
||||||
|
productId: entry.key.uuid,
|
||||||
|
count: entry.value,
|
||||||
|
productName: entry.key.name ?? 'Unnamed',
|
||||||
|
product: entry.key,
|
||||||
|
))
|
||||||
|
.toList();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -189,4 +189,5 @@ class TagChipDisplay extends StatelessWidget {
|
|||||||
))
|
))
|
||||||
.toList();
|
.toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -15,7 +15,6 @@ import 'package:syncrow_web/utils/color_manager.dart';
|
|||||||
|
|
||||||
class AddDeviceTypeModelWidget extends StatelessWidget {
|
class AddDeviceTypeModelWidget extends StatelessWidget {
|
||||||
final List<ProductModel>? products;
|
final List<ProductModel>? products;
|
||||||
final ValueChanged<List<SelectedProduct>>? onProductsSelected;
|
|
||||||
final List<SelectedProduct>? initialSelectedProducts;
|
final List<SelectedProduct>? initialSelectedProducts;
|
||||||
final List<SubspaceTemplateModel>? subspaces;
|
final List<SubspaceTemplateModel>? subspaces;
|
||||||
final List<TagModel>? spaceTagModels;
|
final List<TagModel>? spaceTagModels;
|
||||||
@ -26,7 +25,6 @@ class AddDeviceTypeModelWidget extends StatelessWidget {
|
|||||||
{super.key,
|
{super.key,
|
||||||
this.products,
|
this.products,
|
||||||
this.initialSelectedProducts,
|
this.initialSelectedProducts,
|
||||||
this.onProductsSelected,
|
|
||||||
this.subspaces,
|
this.subspaces,
|
||||||
this.allTags,
|
this.allTags,
|
||||||
this.spaceTagModels,
|
this.spaceTagModels,
|
||||||
|
|||||||
Reference in New Issue
Block a user