Enhance Space Management Features with Tag Assignment Improvements:

- Introduced UUID for ProductAllocation to ensure unique identification.
- Refactored AssignTagsDialog to manage tag assignments and validation more effectively, including error handling for empty tags and duplicate tag usage.
- Updated AssignTagsTable to support dynamic product allocation management and improved UI interactions.
- Enhanced AddDeviceTypeWidget to maintain selected products and handle increment/decrement actions, improving user experience during device type selection.
- Added AssignTagsErrorMessages widget for better error visibility in tag assignment process.
This commit is contained in:
Faris Armoush
2025-07-07 14:26:59 +03:00
parent ddfd4ee153
commit 3101960201
8 changed files with 463 additions and 183 deletions

View File

@ -1,9 +1,11 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_svg/svg.dart';
import 'package:syncrow_web/common/edit_chip.dart';
import 'package:syncrow_web/pages/space_management_v2/modules/space_details/domain/models/space_details_model.dart';
import 'package:syncrow_web/pages/space_management_v2/modules/space_details/presentation/widgets/button_content_widget.dart';
import 'package:syncrow_web/pages/space_management_v2/modules/tags/presentation/widgets/assign_tags_dialog.dart';
import 'package:syncrow_web/pages/space_management_v2/modules/update_space/presentation/bloc/space_details_model_bloc/space_details_model_bloc.dart';
import 'package:syncrow_web/utils/color_manager.dart';
import 'package:syncrow_web/utils/constants/assets.dart';
import 'package:syncrow_web/utils/enum/device_types.dart';
@ -19,11 +21,18 @@ class SpaceDetailsDevicesBox extends StatelessWidget {
@override
Widget build(BuildContext context) {
final productAllocations = space.productAllocations;
final subspaces = space.subspaces;
final isAnySubspaceHasProductAllocations =
subspaces.any((subspace) => subspace.productAllocations.isNotEmpty);
if (productAllocations.isNotEmpty || isAnySubspaceHasProductAllocations) {
final allAllocations = [
...space.productAllocations,
...space.subspaces.expand((s) => s.productAllocations),
];
if (allAllocations.isNotEmpty) {
final productCounts = <String, int>{};
for (final allocation in allAllocations) {
final productType = allocation.product.productType;
productCounts[productType] = (productCounts[productType] ?? 0) + 1;
}
return Container(
width: double.infinity,
padding: const EdgeInsets.all(8),
@ -39,20 +48,23 @@ class SpaceDetailsDevicesBox extends StatelessWidget {
spacing: 8.0,
runSpacing: 8.0,
children: [
...productAllocations.map(
(entry) => Chip(
...productCounts.entries.map((entry) {
final productType = entry.key;
final count = entry.value;
return Chip(
avatar: SizedBox(
width: 24,
height: 24,
child: SvgPicture.asset(
_getDeviceIcon(entry.product.productType),
_getDeviceIcon(productType),
fit: BoxFit.contain,
),
),
label: Text(
entry.product.productType,
style: context.textTheme.bodySmall
?.copyWith(color: ColorsManager.spaceColor),
'x$count',
style: context.textTheme.bodySmall?.copyWith(
color: ColorsManager.spaceColor,
),
),
backgroundColor: ColorsManager.whiteColors,
shape: RoundedRectangleBorder(
@ -61,11 +73,9 @@ class SpaceDetailsDevicesBox extends StatelessWidget {
color: ColorsManager.spaceColor,
),
),
),
),
EditChip(
onTap: () => _showAssignTagsDialog(context),
),
);
}),
EditChip(onTap: () => _showAssignTagsDialog(context)),
],
),
);
@ -87,10 +97,16 @@ class SpaceDetailsDevicesBox extends StatelessWidget {
}
void _showAssignTagsDialog(BuildContext context) {
showDialog<void>(
showDialog<SpaceDetailsModel>(
context: context,
builder: (context) => AssignTagsDialog(space: space),
);
).then((resultSpace) {
if (resultSpace != null) {
if (context.mounted) {
context.read<SpaceDetailsModelBloc>().add(UpdateSpaceDetails(resultSpace));
}
}
});
}
String _getDeviceIcon(String productType) =>